From 4080a8945430540f0c51721439f10f334d985798 Mon Sep 17 00:00:00 2001 From: Dmytro Cherepov Date: Wed, 20 Sep 2023 00:50:00 +0300 Subject: [PATCH 1/6] added tests for Fruit Shop --- src/main/java/core/basesyntax/FruitShop.java | 53 ++++++++++++ src/main/java/core/basesyntax/HelloWorld.java | 7 -- src/main/java/core/basesyntax/db/Storage.java | 8 ++ .../excteption/InvalidDataException.java | 7 ++ .../handlers/BalanceOperationHandler.java | 12 +++ .../handlers/PurchaseOperationHandler.java | 18 ++++ .../handlers/ReturnOperationHandler.java | 15 ++++ .../handlers/SupplyOperationHandler.java | 15 ++++ .../basesyntax/model/FruitTransaction.java | 83 +++++++++++++++++++ .../services/DataProcessorService.java | 8 ++ .../services/FileReaderService.java | 7 ++ .../services/FileWriterService.java | 5 ++ .../services/OperationProcessor.java | 8 ++ .../services/ReportCreatorService.java | 5 ++ .../impl/DataProcessorServiceImpl.java | 32 +++++++ .../services/impl/FileReaderServiceImpl.java | 25 ++++++ .../services/impl/FileWriterServiceImpl.java | 17 ++++ .../services/impl/OperationProcessorImpl.java | 21 +++++ .../impl/ReportCreatorServiceImpl.java | 20 +++++ .../basesyntax/strategy/OperationHandler.java | 7 ++ src/main/java/resources/input.csv | 9 ++ src/main/java/resources/output.csv | 3 + .../handlers/BalanceOperationHandlerTest.java | 40 +++++++++ .../PurchaseOperationHandlerTest.java | 46 ++++++++++ .../handlers/ReturnOperationHandlerTest.java | 35 ++++++++ .../handlers/SupplyOperationHandlerTest.java | 35 ++++++++ .../services/DataProcessorServiceTest.java | 50 +++++++++++ .../services/FileReaderServiceTest.java | 37 +++++++++ .../services/FileWriterServiceTest.java | 42 ++++++++++ .../services/OperationProcessorTest.java | 51 ++++++++++++ .../services/ReportCreatorServiceTest.java | 38 +++++++++ src/test/java/resources/report.csv | 3 + src/test/java/resources/test.csv | 4 + 33 files changed, 759 insertions(+), 7 deletions(-) create mode 100644 src/main/java/core/basesyntax/FruitShop.java delete mode 100644 src/main/java/core/basesyntax/HelloWorld.java create mode 100644 src/main/java/core/basesyntax/db/Storage.java create mode 100644 src/main/java/core/basesyntax/excteption/InvalidDataException.java create mode 100644 src/main/java/core/basesyntax/handlers/BalanceOperationHandler.java create mode 100644 src/main/java/core/basesyntax/handlers/PurchaseOperationHandler.java create mode 100644 src/main/java/core/basesyntax/handlers/ReturnOperationHandler.java create mode 100644 src/main/java/core/basesyntax/handlers/SupplyOperationHandler.java create mode 100644 src/main/java/core/basesyntax/model/FruitTransaction.java create mode 100644 src/main/java/core/basesyntax/services/DataProcessorService.java create mode 100644 src/main/java/core/basesyntax/services/FileReaderService.java create mode 100644 src/main/java/core/basesyntax/services/FileWriterService.java create mode 100644 src/main/java/core/basesyntax/services/OperationProcessor.java create mode 100644 src/main/java/core/basesyntax/services/ReportCreatorService.java create mode 100644 src/main/java/core/basesyntax/services/impl/DataProcessorServiceImpl.java create mode 100644 src/main/java/core/basesyntax/services/impl/FileReaderServiceImpl.java create mode 100644 src/main/java/core/basesyntax/services/impl/FileWriterServiceImpl.java create mode 100644 src/main/java/core/basesyntax/services/impl/OperationProcessorImpl.java create mode 100644 src/main/java/core/basesyntax/services/impl/ReportCreatorServiceImpl.java create mode 100644 src/main/java/core/basesyntax/strategy/OperationHandler.java create mode 100644 src/main/java/resources/input.csv create mode 100644 src/main/java/resources/output.csv create mode 100644 src/test/java/core/basesyntax/handlers/BalanceOperationHandlerTest.java create mode 100644 src/test/java/core/basesyntax/handlers/PurchaseOperationHandlerTest.java create mode 100644 src/test/java/core/basesyntax/handlers/ReturnOperationHandlerTest.java create mode 100644 src/test/java/core/basesyntax/handlers/SupplyOperationHandlerTest.java create mode 100644 src/test/java/core/basesyntax/services/DataProcessorServiceTest.java create mode 100644 src/test/java/core/basesyntax/services/FileReaderServiceTest.java create mode 100644 src/test/java/core/basesyntax/services/FileWriterServiceTest.java create mode 100644 src/test/java/core/basesyntax/services/OperationProcessorTest.java create mode 100644 src/test/java/core/basesyntax/services/ReportCreatorServiceTest.java create mode 100644 src/test/java/resources/report.csv create mode 100644 src/test/java/resources/test.csv diff --git a/src/main/java/core/basesyntax/FruitShop.java b/src/main/java/core/basesyntax/FruitShop.java new file mode 100644 index 0000000000..d5c2942101 --- /dev/null +++ b/src/main/java/core/basesyntax/FruitShop.java @@ -0,0 +1,53 @@ +package core.basesyntax; + +import core.basesyntax.handlers.BalanceOperationHandler; +import core.basesyntax.handlers.PurchaseOperationHandler; +import core.basesyntax.handlers.ReturnOperationHandler; +import core.basesyntax.handlers.SupplyOperationHandler; +import core.basesyntax.model.FruitTransaction; +import core.basesyntax.services.DataProcessorService; +import core.basesyntax.services.FileReaderService; +import core.basesyntax.services.FileWriterService; +import core.basesyntax.services.OperationProcessor; +import core.basesyntax.services.ReportCreatorService; +import core.basesyntax.services.impl.DataProcessorServiceImpl; +import core.basesyntax.services.impl.FileReaderServiceImpl; +import core.basesyntax.services.impl.FileWriterServiceImpl; +import core.basesyntax.services.impl.OperationProcessorImpl; +import core.basesyntax.services.impl.ReportCreatorServiceImpl; +import core.basesyntax.strategy.OperationHandler; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class FruitShop { + private static final String INPUT_FILE_PATH = "src/main/java/resources/input.csv"; + private static final String OUTPUT_FILE_PATH = "src/main/java/resources/output.csv"; + + public static void main(String[] args) { + FileReaderService fileReaderService = new FileReaderServiceImpl(); + List lines = fileReaderService.readFromFile(INPUT_FILE_PATH); + DataProcessorService dataProcessorService = new DataProcessorServiceImpl(); + + Map operationMap = getOperationOperationMap(); + + OperationProcessor operationService = new OperationProcessorImpl(operationMap); + List fruitTransactionList = dataProcessorService.processInputData(lines); + operationService.manageTransactions(fruitTransactionList); + + ReportCreatorService reportCreatorService = new ReportCreatorServiceImpl(); + String report = reportCreatorService.createReport(); + + FileWriterService fileWriterService = new FileWriterServiceImpl(); + fileWriterService.writeToFile(OUTPUT_FILE_PATH, report); + } + + private static Map getOperationOperationMap() { + Map operationMap = new HashMap<>(); + operationMap.put(FruitTransaction.Operation.BALANCE, new BalanceOperationHandler()); + operationMap.put(FruitTransaction.Operation.SUPPLY, new SupplyOperationHandler()); + operationMap.put(FruitTransaction.Operation.PURCHASE, new PurchaseOperationHandler()); + operationMap.put(FruitTransaction.Operation.RETURN, new ReturnOperationHandler()); + return operationMap; + } +} diff --git a/src/main/java/core/basesyntax/HelloWorld.java b/src/main/java/core/basesyntax/HelloWorld.java deleted file mode 100644 index e758b17650..0000000000 --- a/src/main/java/core/basesyntax/HelloWorld.java +++ /dev/null @@ -1,7 +0,0 @@ -package core.basesyntax; - -/** - * Feel free to remove this class and create your own. - */ -public class HelloWorld { -} diff --git a/src/main/java/core/basesyntax/db/Storage.java b/src/main/java/core/basesyntax/db/Storage.java new file mode 100644 index 0000000000..cc38189c14 --- /dev/null +++ b/src/main/java/core/basesyntax/db/Storage.java @@ -0,0 +1,8 @@ +package core.basesyntax.db; + +import java.util.HashMap; +import java.util.Map; + +public class Storage { + public static final Map STORAGE = new HashMap<>(); +} diff --git a/src/main/java/core/basesyntax/excteption/InvalidDataException.java b/src/main/java/core/basesyntax/excteption/InvalidDataException.java new file mode 100644 index 0000000000..0d5a62b785 --- /dev/null +++ b/src/main/java/core/basesyntax/excteption/InvalidDataException.java @@ -0,0 +1,7 @@ +package core.basesyntax.excteption; + +public class InvalidDataException extends RuntimeException { + public InvalidDataException(String message) { + super(message); + } +} diff --git a/src/main/java/core/basesyntax/handlers/BalanceOperationHandler.java b/src/main/java/core/basesyntax/handlers/BalanceOperationHandler.java new file mode 100644 index 0000000000..852ea36be2 --- /dev/null +++ b/src/main/java/core/basesyntax/handlers/BalanceOperationHandler.java @@ -0,0 +1,12 @@ +package core.basesyntax.handlers; + +import core.basesyntax.db.Storage; +import core.basesyntax.model.FruitTransaction; +import core.basesyntax.strategy.OperationHandler; + +public class BalanceOperationHandler implements OperationHandler { + @Override + public void calculateOperation(FruitTransaction transaction) { + Storage.STORAGE.put(transaction.getFruit(), transaction.getQuantity()); + } +} diff --git a/src/main/java/core/basesyntax/handlers/PurchaseOperationHandler.java b/src/main/java/core/basesyntax/handlers/PurchaseOperationHandler.java new file mode 100644 index 0000000000..7effaec9ae --- /dev/null +++ b/src/main/java/core/basesyntax/handlers/PurchaseOperationHandler.java @@ -0,0 +1,18 @@ +package core.basesyntax.handlers; + +import core.basesyntax.db.Storage; +import core.basesyntax.model.FruitTransaction; +import core.basesyntax.strategy.OperationHandler; + +public class PurchaseOperationHandler implements OperationHandler { + @Override + public void calculateOperation(FruitTransaction transaction) { + int currentAmount = Storage.STORAGE.get(transaction.getFruit()); + int quantity = transaction.getQuantity(); + int purchaseResult = currentAmount - quantity; + if (purchaseResult < 0) { + throw new RuntimeException("Not enough fruits in storage"); + } + Storage.STORAGE.put(transaction.getFruit(), purchaseResult); + } +} diff --git a/src/main/java/core/basesyntax/handlers/ReturnOperationHandler.java b/src/main/java/core/basesyntax/handlers/ReturnOperationHandler.java new file mode 100644 index 0000000000..15f188ea5c --- /dev/null +++ b/src/main/java/core/basesyntax/handlers/ReturnOperationHandler.java @@ -0,0 +1,15 @@ +package core.basesyntax.handlers; + +import core.basesyntax.db.Storage; +import core.basesyntax.model.FruitTransaction; +import core.basesyntax.strategy.OperationHandler; + +public class ReturnOperationHandler implements OperationHandler { + @Override + public void calculateOperation(FruitTransaction transaction) { + int currentAmount = Storage.STORAGE.get(transaction.getFruit()); + int quantity = transaction.getQuantity(); + int returnResult = currentAmount + quantity; + Storage.STORAGE.put(transaction.getFruit(), returnResult); + } +} diff --git a/src/main/java/core/basesyntax/handlers/SupplyOperationHandler.java b/src/main/java/core/basesyntax/handlers/SupplyOperationHandler.java new file mode 100644 index 0000000000..b973ecf2c4 --- /dev/null +++ b/src/main/java/core/basesyntax/handlers/SupplyOperationHandler.java @@ -0,0 +1,15 @@ +package core.basesyntax.handlers; + +import core.basesyntax.db.Storage; +import core.basesyntax.model.FruitTransaction; +import core.basesyntax.strategy.OperationHandler; + +public class SupplyOperationHandler implements OperationHandler { + @Override + public void calculateOperation(FruitTransaction transaction) { + int currentAmount = Storage.STORAGE.get(transaction.getFruit()); + int quantity = transaction.getQuantity(); + int supplyResult = currentAmount + quantity; + Storage.STORAGE.put(transaction.getFruit(), supplyResult); + } +} diff --git a/src/main/java/core/basesyntax/model/FruitTransaction.java b/src/main/java/core/basesyntax/model/FruitTransaction.java new file mode 100644 index 0000000000..92590825b5 --- /dev/null +++ b/src/main/java/core/basesyntax/model/FruitTransaction.java @@ -0,0 +1,83 @@ +package core.basesyntax.model; + +import java.util.Arrays; +import java.util.Objects; + +public class FruitTransaction { + private Operation operation; + private String fruit; + private int quantity; + + public FruitTransaction(Operation operation, String fruit, int quantity) { + this.operation = operation; + this.fruit = fruit; + this.quantity = quantity; + } + + public Operation getOperation() { + return operation; + } + + public void setOperation(Operation operation) { + this.operation = operation; + } + + public String getFruit() { + return fruit; + } + + public void setFruit(String fruit) { + this.fruit = fruit; + } + + public int getQuantity() { + return quantity; + } + + public void setQuantity(int quantity) { + this.quantity = quantity; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + FruitTransaction that = (FruitTransaction) o; + return quantity == that.quantity + && operation == that.operation + && Objects.equals(fruit, that.fruit); + } + + @Override + public int hashCode() { + return Objects.hash(operation, fruit, quantity); + } + + public enum Operation { + BALANCE("b"), + SUPPLY("s"), + PURCHASE("p"), + RETURN("r"); + + private String code; + + Operation(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + + public static Operation getOperationByCode(String code) { + return Arrays.stream(Operation.values()) + .filter(o -> o.getCode().equals(code)) + .findAny() + .orElseThrow(() -> new RuntimeException("No such operation")); + } + } +} diff --git a/src/main/java/core/basesyntax/services/DataProcessorService.java b/src/main/java/core/basesyntax/services/DataProcessorService.java new file mode 100644 index 0000000000..0870b4288c --- /dev/null +++ b/src/main/java/core/basesyntax/services/DataProcessorService.java @@ -0,0 +1,8 @@ +package core.basesyntax.services; + +import core.basesyntax.model.FruitTransaction; +import java.util.List; + +public interface DataProcessorService { + List processInputData(List dataFromFile); +} diff --git a/src/main/java/core/basesyntax/services/FileReaderService.java b/src/main/java/core/basesyntax/services/FileReaderService.java new file mode 100644 index 0000000000..51aebf36e1 --- /dev/null +++ b/src/main/java/core/basesyntax/services/FileReaderService.java @@ -0,0 +1,7 @@ +package core.basesyntax.services; + +import java.util.List; + +public interface FileReaderService { + List readFromFile(String fileName); +} diff --git a/src/main/java/core/basesyntax/services/FileWriterService.java b/src/main/java/core/basesyntax/services/FileWriterService.java new file mode 100644 index 0000000000..8d7fa624c0 --- /dev/null +++ b/src/main/java/core/basesyntax/services/FileWriterService.java @@ -0,0 +1,5 @@ +package core.basesyntax.services; + +public interface FileWriterService { + void writeToFile(String fileName, String report); +} diff --git a/src/main/java/core/basesyntax/services/OperationProcessor.java b/src/main/java/core/basesyntax/services/OperationProcessor.java new file mode 100644 index 0000000000..36a8e78dc0 --- /dev/null +++ b/src/main/java/core/basesyntax/services/OperationProcessor.java @@ -0,0 +1,8 @@ +package core.basesyntax.services; + +import core.basesyntax.model.FruitTransaction; +import java.util.List; + +public interface OperationProcessor { + void manageTransactions(List transactions); +} diff --git a/src/main/java/core/basesyntax/services/ReportCreatorService.java b/src/main/java/core/basesyntax/services/ReportCreatorService.java new file mode 100644 index 0000000000..c608829278 --- /dev/null +++ b/src/main/java/core/basesyntax/services/ReportCreatorService.java @@ -0,0 +1,5 @@ +package core.basesyntax.services; + +public interface ReportCreatorService { + String createReport(); +} diff --git a/src/main/java/core/basesyntax/services/impl/DataProcessorServiceImpl.java b/src/main/java/core/basesyntax/services/impl/DataProcessorServiceImpl.java new file mode 100644 index 0000000000..3c838aa87b --- /dev/null +++ b/src/main/java/core/basesyntax/services/impl/DataProcessorServiceImpl.java @@ -0,0 +1,32 @@ +package core.basesyntax.services.impl; + +import core.basesyntax.excteption.InvalidDataException; +import core.basesyntax.model.FruitTransaction; +import core.basesyntax.services.DataProcessorService; +import java.util.List; + +public class DataProcessorServiceImpl implements DataProcessorService { + private static final String SPLIT_DELIMITER = ","; + private static final int OPERATION_TYPE_INDEX = 0; + private static final int FRUIT_TYPE_INDEX = 1; + private static final int FRUIT_QUANTITY_INDEX = 2; + + @Override + public List processInputData(List dataFromFile) { + return dataFromFile.stream() + .map(this::getFruitTransaction) + .toList(); + } + + private FruitTransaction getFruitTransaction(String data) { + String[] processedData = data.split(SPLIT_DELIMITER); + FruitTransaction.Operation operation = FruitTransaction.Operation + .getOperationByCode(processedData[OPERATION_TYPE_INDEX]); + String fruitType = processedData[FRUIT_TYPE_INDEX]; + int fruitQuantity = Integer.parseInt(processedData[FRUIT_QUANTITY_INDEX]); + if (fruitQuantity < 0) { + throw new InvalidDataException("Invalid Quantity,fruit quantity is: " + fruitQuantity); + } + return new FruitTransaction(operation, fruitType, fruitQuantity); + } +} diff --git a/src/main/java/core/basesyntax/services/impl/FileReaderServiceImpl.java b/src/main/java/core/basesyntax/services/impl/FileReaderServiceImpl.java new file mode 100644 index 0000000000..ab96d57fa3 --- /dev/null +++ b/src/main/java/core/basesyntax/services/impl/FileReaderServiceImpl.java @@ -0,0 +1,25 @@ +package core.basesyntax.services.impl; + +import core.basesyntax.services.FileReaderService; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +public class FileReaderServiceImpl implements FileReaderService { + private static final int SKIP_LINE = 1; + + @Override + public List readFromFile(String fileName) { + List linesFromFile = new ArrayList<>(); + Path path = Paths.get(fileName); + try { + Files.lines(path).skip(SKIP_LINE).forEach(linesFromFile::add); + } catch (IOException e) { + throw new RuntimeException("Can't read data from file : " + fileName); + } + return linesFromFile; + } +} diff --git a/src/main/java/core/basesyntax/services/impl/FileWriterServiceImpl.java b/src/main/java/core/basesyntax/services/impl/FileWriterServiceImpl.java new file mode 100644 index 0000000000..dedeeb3b39 --- /dev/null +++ b/src/main/java/core/basesyntax/services/impl/FileWriterServiceImpl.java @@ -0,0 +1,17 @@ +package core.basesyntax.services.impl; + +import core.basesyntax.services.FileWriterService; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class FileWriterServiceImpl implements FileWriterService { + @Override + public void writeToFile(String filePath, String report) { + try { + Files.writeString(Paths.get(filePath), report); + } catch (IOException e) { + throw new RuntimeException("Can't find file by path" + filePath); + } + } +} diff --git a/src/main/java/core/basesyntax/services/impl/OperationProcessorImpl.java b/src/main/java/core/basesyntax/services/impl/OperationProcessorImpl.java new file mode 100644 index 0000000000..b27035e0ad --- /dev/null +++ b/src/main/java/core/basesyntax/services/impl/OperationProcessorImpl.java @@ -0,0 +1,21 @@ +package core.basesyntax.services.impl; + +import core.basesyntax.model.FruitTransaction; +import core.basesyntax.services.OperationProcessor; +import core.basesyntax.strategy.OperationHandler; +import java.util.List; +import java.util.Map; + +public class OperationProcessorImpl implements OperationProcessor { + private final Map processedOperations; + + public OperationProcessorImpl( + Map processedOperations) { + this.processedOperations = processedOperations; + } + + @Override + public void manageTransactions(List transactions) { + transactions.forEach(t -> processedOperations.get(t.getOperation()).calculateOperation(t)); + } +} diff --git a/src/main/java/core/basesyntax/services/impl/ReportCreatorServiceImpl.java b/src/main/java/core/basesyntax/services/impl/ReportCreatorServiceImpl.java new file mode 100644 index 0000000000..d2df59a703 --- /dev/null +++ b/src/main/java/core/basesyntax/services/impl/ReportCreatorServiceImpl.java @@ -0,0 +1,20 @@ +package core.basesyntax.services.impl; + +import core.basesyntax.db.Storage; +import core.basesyntax.services.ReportCreatorService; + +public class ReportCreatorServiceImpl implements ReportCreatorService { + private static final String DEFAULT_MESSAGE = "fruit,quantity"; + private static final String SPLIT_DELIMITER = ","; + + @Override + public String createReport() { + StringBuilder reportBuilder = new StringBuilder(); + reportBuilder.append(DEFAULT_MESSAGE).append(System.lineSeparator()); + Storage.STORAGE.forEach((key, value) -> reportBuilder.append(key) + .append(SPLIT_DELIMITER) + .append(value) + .append(System.lineSeparator())); + return reportBuilder.toString(); + } +} diff --git a/src/main/java/core/basesyntax/strategy/OperationHandler.java b/src/main/java/core/basesyntax/strategy/OperationHandler.java new file mode 100644 index 0000000000..bd659dcb85 --- /dev/null +++ b/src/main/java/core/basesyntax/strategy/OperationHandler.java @@ -0,0 +1,7 @@ +package core.basesyntax.strategy; + +import core.basesyntax.model.FruitTransaction; + +public interface OperationHandler { + void calculateOperation(FruitTransaction transaction); +} diff --git a/src/main/java/resources/input.csv b/src/main/java/resources/input.csv new file mode 100644 index 0000000000..c771f259d3 --- /dev/null +++ b/src/main/java/resources/input.csv @@ -0,0 +1,9 @@ +type,fruit,quantity +b,banana,20 +b,apple,100 +s,banana,100 +p,banana,13 +r,apple,10 +p,apple,20 +p,banana,5 +s,banana,50 \ No newline at end of file diff --git a/src/main/java/resources/output.csv b/src/main/java/resources/output.csv new file mode 100644 index 0000000000..6158e4419c --- /dev/null +++ b/src/main/java/resources/output.csv @@ -0,0 +1,3 @@ +fruit,quantity +banana,152 +apple,90 diff --git a/src/test/java/core/basesyntax/handlers/BalanceOperationHandlerTest.java b/src/test/java/core/basesyntax/handlers/BalanceOperationHandlerTest.java new file mode 100644 index 0000000000..1c7f98226b --- /dev/null +++ b/src/test/java/core/basesyntax/handlers/BalanceOperationHandlerTest.java @@ -0,0 +1,40 @@ +package core.basesyntax.handlers; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import core.basesyntax.db.Storage; +import core.basesyntax.model.FruitTransaction; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class BalanceOperationHandlerTest { + private static BalanceOperationHandler balanceOperationHandler; + + @BeforeAll + static void beforeAll() { + balanceOperationHandler = new BalanceOperationHandler(); + } + + @AfterEach + void tearDown() { + Storage.STORAGE.clear(); + } + + @Test + void calculateOperation_ok() { + FruitTransaction bananaTransaction = new FruitTransaction( + FruitTransaction.Operation.BALANCE, "banana", 120 + ); + assertDoesNotThrow(() -> balanceOperationHandler.calculateOperation(bananaTransaction)); + FruitTransaction appleTransaction = new FruitTransaction( + FruitTransaction.Operation.BALANCE, "apple", 50 + ); + assertDoesNotThrow(() -> balanceOperationHandler.calculateOperation(appleTransaction)); + int expectedBanana = Storage.STORAGE.get("banana"); + assertEquals(expectedBanana, 120); + int expectedApple = Storage.STORAGE.get("apple"); + assertEquals(expectedApple, 50); + } +} diff --git a/src/test/java/core/basesyntax/handlers/PurchaseOperationHandlerTest.java b/src/test/java/core/basesyntax/handlers/PurchaseOperationHandlerTest.java new file mode 100644 index 0000000000..b2843ce2a3 --- /dev/null +++ b/src/test/java/core/basesyntax/handlers/PurchaseOperationHandlerTest.java @@ -0,0 +1,46 @@ +package core.basesyntax.handlers; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import core.basesyntax.db.Storage; +import core.basesyntax.model.FruitTransaction; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class PurchaseOperationHandlerTest { + private static PurchaseOperationHandler purchaseOperationHandler; + + @BeforeAll + static void beforeAll() { + purchaseOperationHandler = new PurchaseOperationHandler(); + } + + @AfterEach + void tearDown() { + Storage.STORAGE.clear(); + } + + @Test + void processPurchaseOperation_ok() { + Storage.STORAGE.put("banana", 100); + FruitTransaction fruitTransaction = new FruitTransaction( + FruitTransaction.Operation.PURCHASE, "banana", 70 + ); + assertDoesNotThrow(() -> purchaseOperationHandler.calculateOperation(fruitTransaction)); + int fruitsInStorage = Storage.STORAGE.get("banana"); + assertEquals(30, fruitsInStorage); + } + + @Test + void processPurchaseOperation_quantityMoreAmount_notOk() { + Storage.STORAGE.put("banana", 20); + FruitTransaction fruitTransaction = new FruitTransaction( + FruitTransaction.Operation.PURCHASE, "banana", 70 + ); + assertThrows(RuntimeException.class, + () -> purchaseOperationHandler.calculateOperation(fruitTransaction)); + } +} diff --git a/src/test/java/core/basesyntax/handlers/ReturnOperationHandlerTest.java b/src/test/java/core/basesyntax/handlers/ReturnOperationHandlerTest.java new file mode 100644 index 0000000000..e68eb6f071 --- /dev/null +++ b/src/test/java/core/basesyntax/handlers/ReturnOperationHandlerTest.java @@ -0,0 +1,35 @@ +package core.basesyntax.handlers; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import core.basesyntax.db.Storage; +import core.basesyntax.model.FruitTransaction; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class ReturnOperationHandlerTest { + private static ReturnOperationHandler returnOperationHandler; + + @BeforeAll + static void beforeAll() { + returnOperationHandler = new ReturnOperationHandler(); + } + + @AfterEach + void tearDown() { + Storage.STORAGE.clear(); + } + + @Test + void processReturnOperation_ok() { + Storage.STORAGE.put("banana", 15); + FruitTransaction fruitTransaction = new FruitTransaction( + FruitTransaction.Operation.RETURN, "banana", 100 + ); + assertDoesNotThrow(() -> returnOperationHandler.calculateOperation(fruitTransaction)); + int actualAmount = Storage.STORAGE.get("banana"); + assertEquals(115, actualAmount); + } +} diff --git a/src/test/java/core/basesyntax/handlers/SupplyOperationHandlerTest.java b/src/test/java/core/basesyntax/handlers/SupplyOperationHandlerTest.java new file mode 100644 index 0000000000..e864227e13 --- /dev/null +++ b/src/test/java/core/basesyntax/handlers/SupplyOperationHandlerTest.java @@ -0,0 +1,35 @@ +package core.basesyntax.handlers; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import core.basesyntax.db.Storage; +import core.basesyntax.model.FruitTransaction; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class SupplyOperationHandlerTest { + private static SupplyOperationHandler supplyOperationHandler; + + @BeforeAll + static void beforeAll() { + supplyOperationHandler = new SupplyOperationHandler(); + } + + @AfterEach + void tearDown() { + Storage.STORAGE.clear(); + } + + @Test + void processSupply_ok() { + Storage.STORAGE.put("banana", 15); + FruitTransaction fruitTransaction = new FruitTransaction( + FruitTransaction.Operation.RETURN, "banana", 100); + assertDoesNotThrow(() -> supplyOperationHandler.calculateOperation(fruitTransaction) + ); + int actualAmount = Storage.STORAGE.get("banana"); + assertEquals(115, actualAmount); + } +} diff --git a/src/test/java/core/basesyntax/services/DataProcessorServiceTest.java b/src/test/java/core/basesyntax/services/DataProcessorServiceTest.java new file mode 100644 index 0000000000..7c9b3328bb --- /dev/null +++ b/src/test/java/core/basesyntax/services/DataProcessorServiceTest.java @@ -0,0 +1,50 @@ +package core.basesyntax.services; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import core.basesyntax.db.Storage; +import core.basesyntax.model.FruitTransaction; +import core.basesyntax.services.impl.DataProcessorServiceImpl; +import java.util.List; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class DataProcessorServiceTest { + private static DataProcessorService dataProcessorService; + + @BeforeAll + static void beforeAll() { + dataProcessorService = new DataProcessorServiceImpl(); + } + + @AfterEach + void tearDown() { + Storage.STORAGE.clear(); + } + + @Test + void processData_validData_ok() { + List data = List.of("b,banana,10", "b,apple,20", "s,banana,10"); + List expected = List.of( + new FruitTransaction(FruitTransaction.Operation.BALANCE, "banana", 10), + new FruitTransaction(FruitTransaction.Operation.BALANCE, "apple", 20), + new FruitTransaction(FruitTransaction.Operation.SUPPLY, "banana", 10) + ); + List fruitTransactions = dataProcessorService.processInputData(data); + assertEquals(expected, fruitTransactions); + } + + @Test + void processData_invalidQuantity_notOk() { + List data = List.of("b,banana,-200", "b,apple,20", "s,banana,10"); + assertThrows(RuntimeException.class, () -> dataProcessorService.processInputData(data)); + } + + @Test + void processData_invalidOperationType_notOk() { + List data = List.of("buy,banana,-200", "b,apple,20", "s,banana,10"); + assertThrows(RuntimeException.class, () -> dataProcessorService.processInputData(data)); + } +} diff --git a/src/test/java/core/basesyntax/services/FileReaderServiceTest.java b/src/test/java/core/basesyntax/services/FileReaderServiceTest.java new file mode 100644 index 0000000000..dc2e6ba728 --- /dev/null +++ b/src/test/java/core/basesyntax/services/FileReaderServiceTest.java @@ -0,0 +1,37 @@ +package core.basesyntax.services; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import core.basesyntax.services.impl.FileReaderServiceImpl; +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class FileReaderServiceTest { + private static FileReaderService fileReaderService; + private static final String VALID_FILE_PATH = "src/test/java/resources/test.csv"; + private static final String INVALID_FILE_PATH = "src/test/java/resources/InvalidTest.csv"; + + @BeforeAll + static void beforeAll() { + fileReaderService = new FileReaderServiceImpl(); + } + + @Test + void readData_existingFile_ok() { + List expected = fileReaderService.readFromFile(VALID_FILE_PATH); + List actual = List.of( + "b,banana,20", + "b,apple,40", + "s,banana,40" + ); + assertEquals(expected,actual); + } + + @Test + void readData_notExistingFile_notOk() { + assertThrows(RuntimeException.class, + () -> fileReaderService.readFromFile(INVALID_FILE_PATH)); + } +} diff --git a/src/test/java/core/basesyntax/services/FileWriterServiceTest.java b/src/test/java/core/basesyntax/services/FileWriterServiceTest.java new file mode 100644 index 0000000000..1465faf1c3 --- /dev/null +++ b/src/test/java/core/basesyntax/services/FileWriterServiceTest.java @@ -0,0 +1,42 @@ +package core.basesyntax.services; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import core.basesyntax.services.impl.FileWriterServiceImpl; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class FileWriterServiceTest { + private static FileWriterService fileWriterService; + private static final String VALID_FILE_PATH = "src/test/java/resources/report.csv"; + private static final String INVALID_FILE_PATH = "src/test/java/resources/.../"; + + @BeforeAll + static void beforeAll() { + fileWriterService = new FileWriterServiceImpl(); + } + + @Test + void writeTo_validFilePath_ok() throws IOException { + String report = "fruit,quantity" + System.lineSeparator() + + "banana,152" + System.lineSeparator() + "apple,90"; + assertDoesNotThrow(() -> fileWriterService.writeToFile(VALID_FILE_PATH, report)); + assertEquals(Files.readString(Path.of(VALID_FILE_PATH)), report); + + } + + @Test + void writeTo_invalidFilePath_notOk() { + String report = "fruit,quantity" + System.lineSeparator() + + "banana,152" + System.lineSeparator() + "apple,90"; + assertThrows(RuntimeException.class, + () -> fileWriterService.writeToFile(INVALID_FILE_PATH, report) + ); + } +} + diff --git a/src/test/java/core/basesyntax/services/OperationProcessorTest.java b/src/test/java/core/basesyntax/services/OperationProcessorTest.java new file mode 100644 index 0000000000..bae77a988a --- /dev/null +++ b/src/test/java/core/basesyntax/services/OperationProcessorTest.java @@ -0,0 +1,51 @@ +package core.basesyntax.services; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import core.basesyntax.db.Storage; +import core.basesyntax.handlers.BalanceOperationHandler; +import core.basesyntax.handlers.PurchaseOperationHandler; +import core.basesyntax.handlers.ReturnOperationHandler; +import core.basesyntax.handlers.SupplyOperationHandler; +import core.basesyntax.model.FruitTransaction; +import core.basesyntax.services.impl.OperationProcessorImpl; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class OperationProcessorTest { + private static OperationProcessor operationProcessor; + + @BeforeAll + static void beforeAll() { + operationProcessor = new OperationProcessorImpl(Map.of( + FruitTransaction.Operation.BALANCE, new BalanceOperationHandler(), + FruitTransaction.Operation.RETURN, new ReturnOperationHandler(), + FruitTransaction.Operation.SUPPLY, new SupplyOperationHandler(), + FruitTransaction.Operation.PURCHASE, new PurchaseOperationHandler() + )); + } + + @AfterEach + void tearDown() { + Storage.STORAGE.clear(); + } + + @Test + void processOperation_emptyList_notOk() { + assertDoesNotThrow(() -> operationProcessor.manageTransactions(Collections.emptyList())); + } + + @Test + void processOperations_nonEmptyList_ok() { + List transactions = List.of( + new FruitTransaction(FruitTransaction.Operation.BALANCE, "banana", 10), + new FruitTransaction(FruitTransaction.Operation.BALANCE, "apple", 20), + new FruitTransaction(FruitTransaction.Operation.SUPPLY, "banana", 10) + ); + assertDoesNotThrow(() -> operationProcessor.manageTransactions(transactions)); + } +} diff --git a/src/test/java/core/basesyntax/services/ReportCreatorServiceTest.java b/src/test/java/core/basesyntax/services/ReportCreatorServiceTest.java new file mode 100644 index 0000000000..6d168cf4c1 --- /dev/null +++ b/src/test/java/core/basesyntax/services/ReportCreatorServiceTest.java @@ -0,0 +1,38 @@ +package core.basesyntax.services; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import core.basesyntax.db.Storage; +import core.basesyntax.services.impl.ReportCreatorServiceImpl; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class ReportCreatorServiceTest { + private static ReportCreatorService reportCreatorService; + + @BeforeAll + static void beforeAll() { + reportCreatorService = new ReportCreatorServiceImpl(); + } + + @AfterEach + void tearDown() { + Storage.STORAGE.clear(); + } + + @Test + void createReport_emptyData_ok() { + String expected = "fruit,quantity" + System.lineSeparator(); + assertEquals(expected, reportCreatorService.createReport()); + } + + @Test + void createReport_existingData_ok() { + Storage.STORAGE.put("banana", 10); + Storage.STORAGE.put("apple", 20); + String expectedReport = "fruit,quantity" + System.lineSeparator() + + "banana,10" + System.lineSeparator() + "apple,20" + System.lineSeparator(); + assertEquals(expectedReport, reportCreatorService.createReport()); + } +} diff --git a/src/test/java/resources/report.csv b/src/test/java/resources/report.csv new file mode 100644 index 0000000000..d7ee69b6d1 --- /dev/null +++ b/src/test/java/resources/report.csv @@ -0,0 +1,3 @@ +fruit,quantity +banana,152 +apple,90 \ No newline at end of file diff --git a/src/test/java/resources/test.csv b/src/test/java/resources/test.csv new file mode 100644 index 0000000000..f2ec446a8f --- /dev/null +++ b/src/test/java/resources/test.csv @@ -0,0 +1,4 @@ +type,fruit,quantity +b,banana,20 +b,apple,40 +s,banana,40 From 69c1c5a09bc900118cddb14d5040a5be7ac3576f Mon Sep 17 00:00:00 2001 From: Dmytro Cherepov Date: Wed, 20 Sep 2023 12:40:54 +0300 Subject: [PATCH 2/6] added fixes --- .../java/core/basesyntax/services/FileWriterServiceTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/core/basesyntax/services/FileWriterServiceTest.java b/src/test/java/core/basesyntax/services/FileWriterServiceTest.java index 1465faf1c3..d7dd9186e2 100644 --- a/src/test/java/core/basesyntax/services/FileWriterServiceTest.java +++ b/src/test/java/core/basesyntax/services/FileWriterServiceTest.java @@ -14,7 +14,7 @@ class FileWriterServiceTest { private static FileWriterService fileWriterService; private static final String VALID_FILE_PATH = "src/test/java/resources/report.csv"; - private static final String INVALID_FILE_PATH = "src/test/java/resources/.../"; + private static final String INVALID_FILE_PATH = "src/test/java/resources/.."; @BeforeAll static void beforeAll() { @@ -39,4 +39,3 @@ void writeTo_invalidFilePath_notOk() { ); } } - From caea4f8a2a7a95ce8da5839efec66521ecdc16bf Mon Sep 17 00:00:00 2001 From: Dmytro Cherepov Date: Wed, 20 Sep 2023 13:42:21 +0300 Subject: [PATCH 3/6] added tests for task --- .../handlers/BalanceOperationHandler.java | 6 ++++ .../handlers/PurchaseOperationHandler.java | 6 ++++ .../handlers/ReturnOperationHandler.java | 6 ++++ .../handlers/SupplyOperationHandler.java | 6 ++++ .../handlers/BalanceOperationHandlerTest.java | 32 +++++++++++++++++++ .../PurchaseOperationHandlerTest.java | 20 ++++++++++++ .../handlers/ReturnOperationHandlerTest.java | 21 ++++++++++++ .../handlers/SupplyOperationHandlerTest.java | 32 +++++++++++++++++++ .../services/DataProcessorServiceTest.java | 6 ++++ .../services/FileReaderServiceTest.java | 8 +++++ .../services/FileWriterServiceTest.java | 7 ++++ .../services/OperationProcessorTest.java | 8 +++-- .../services/ReportCreatorServiceTest.java | 8 +++++ src/test/java/resources/empty_file_csv | 0 14 files changed, 163 insertions(+), 3 deletions(-) create mode 100644 src/test/java/resources/empty_file_csv diff --git a/src/main/java/core/basesyntax/handlers/BalanceOperationHandler.java b/src/main/java/core/basesyntax/handlers/BalanceOperationHandler.java index 852ea36be2..84895912eb 100644 --- a/src/main/java/core/basesyntax/handlers/BalanceOperationHandler.java +++ b/src/main/java/core/basesyntax/handlers/BalanceOperationHandler.java @@ -1,12 +1,18 @@ package core.basesyntax.handlers; import core.basesyntax.db.Storage; +import core.basesyntax.excteption.InvalidDataException; import core.basesyntax.model.FruitTransaction; import core.basesyntax.strategy.OperationHandler; public class BalanceOperationHandler implements OperationHandler { @Override public void calculateOperation(FruitTransaction transaction) { + if (transaction.getQuantity() < 0) { + throw new InvalidDataException("Negative quantity"); + } else if (transaction.getFruit() == null || transaction.getOperation() == null) { + throw new NullPointerException("Invalid transaction or fruit type"); + } Storage.STORAGE.put(transaction.getFruit(), transaction.getQuantity()); } } diff --git a/src/main/java/core/basesyntax/handlers/PurchaseOperationHandler.java b/src/main/java/core/basesyntax/handlers/PurchaseOperationHandler.java index 7effaec9ae..ce1125bac9 100644 --- a/src/main/java/core/basesyntax/handlers/PurchaseOperationHandler.java +++ b/src/main/java/core/basesyntax/handlers/PurchaseOperationHandler.java @@ -1,12 +1,18 @@ package core.basesyntax.handlers; import core.basesyntax.db.Storage; +import core.basesyntax.excteption.InvalidDataException; import core.basesyntax.model.FruitTransaction; import core.basesyntax.strategy.OperationHandler; public class PurchaseOperationHandler implements OperationHandler { @Override public void calculateOperation(FruitTransaction transaction) { + if (transaction.getQuantity() < 0) { + throw new InvalidDataException("Negative quantity"); + } else if (transaction.getFruit() == null) { + throw new NullPointerException("Invalid fruit type"); + } int currentAmount = Storage.STORAGE.get(transaction.getFruit()); int quantity = transaction.getQuantity(); int purchaseResult = currentAmount - quantity; diff --git a/src/main/java/core/basesyntax/handlers/ReturnOperationHandler.java b/src/main/java/core/basesyntax/handlers/ReturnOperationHandler.java index 15f188ea5c..f679399334 100644 --- a/src/main/java/core/basesyntax/handlers/ReturnOperationHandler.java +++ b/src/main/java/core/basesyntax/handlers/ReturnOperationHandler.java @@ -1,12 +1,18 @@ package core.basesyntax.handlers; import core.basesyntax.db.Storage; +import core.basesyntax.excteption.InvalidDataException; import core.basesyntax.model.FruitTransaction; import core.basesyntax.strategy.OperationHandler; public class ReturnOperationHandler implements OperationHandler { @Override public void calculateOperation(FruitTransaction transaction) { + if (transaction.getQuantity() < 0) { + throw new InvalidDataException("Negative quantity"); + } else if (transaction.getFruit() == null) { + throw new NullPointerException("Invalid fruit type"); + } int currentAmount = Storage.STORAGE.get(transaction.getFruit()); int quantity = transaction.getQuantity(); int returnResult = currentAmount + quantity; diff --git a/src/main/java/core/basesyntax/handlers/SupplyOperationHandler.java b/src/main/java/core/basesyntax/handlers/SupplyOperationHandler.java index b973ecf2c4..eb2e93eada 100644 --- a/src/main/java/core/basesyntax/handlers/SupplyOperationHandler.java +++ b/src/main/java/core/basesyntax/handlers/SupplyOperationHandler.java @@ -1,12 +1,18 @@ package core.basesyntax.handlers; import core.basesyntax.db.Storage; +import core.basesyntax.excteption.InvalidDataException; import core.basesyntax.model.FruitTransaction; import core.basesyntax.strategy.OperationHandler; public class SupplyOperationHandler implements OperationHandler { @Override public void calculateOperation(FruitTransaction transaction) { + if (transaction.getQuantity() < 0) { + throw new InvalidDataException("Negative quantity"); + } else if (transaction.getFruit() == null || transaction.getOperation() == null) { + throw new NullPointerException("Invalid transaction or fruit type"); + } int currentAmount = Storage.STORAGE.get(transaction.getFruit()); int quantity = transaction.getQuantity(); int supplyResult = currentAmount + quantity; diff --git a/src/test/java/core/basesyntax/handlers/BalanceOperationHandlerTest.java b/src/test/java/core/basesyntax/handlers/BalanceOperationHandlerTest.java index 1c7f98226b..691b5a1af9 100644 --- a/src/test/java/core/basesyntax/handlers/BalanceOperationHandlerTest.java +++ b/src/test/java/core/basesyntax/handlers/BalanceOperationHandlerTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import core.basesyntax.db.Storage; import core.basesyntax.model.FruitTransaction; @@ -37,4 +38,35 @@ void calculateOperation_ok() { int expectedApple = Storage.STORAGE.get("apple"); assertEquals(expectedApple, 50); } + + @Test + void calculateOperation_negativeQuantity_notOk() { + FruitTransaction bananaTransaction = new FruitTransaction( + FruitTransaction.Operation.BALANCE, "banana", -100 + ); + assertThrows(RuntimeException.class, + () -> balanceOperationHandler.calculateOperation(bananaTransaction) + ); + } + + @Test + void calculateOperation_nullFruit_notOk() { + FruitTransaction bananaTransaction = new FruitTransaction( + FruitTransaction.Operation.BALANCE, null, 100 + ); + assertThrows(NullPointerException.class, + () -> balanceOperationHandler.calculateOperation(bananaTransaction) + ); + } + + @Test + void calculateOperation_nullOperationType_notOk() { + FruitTransaction bananaTransaction = new FruitTransaction( + null, "banana", 100 + ); + assertThrows(NullPointerException.class, + () -> balanceOperationHandler.calculateOperation(bananaTransaction) + ); + } } + diff --git a/src/test/java/core/basesyntax/handlers/PurchaseOperationHandlerTest.java b/src/test/java/core/basesyntax/handlers/PurchaseOperationHandlerTest.java index b2843ce2a3..90b9373e1f 100644 --- a/src/test/java/core/basesyntax/handlers/PurchaseOperationHandlerTest.java +++ b/src/test/java/core/basesyntax/handlers/PurchaseOperationHandlerTest.java @@ -34,6 +34,26 @@ void processPurchaseOperation_ok() { assertEquals(30, fruitsInStorage); } + @Test + void processPurchaseOperation_nullFruit_notOk() { + Storage.STORAGE.put("banana", 20); + FruitTransaction fruitTransaction = new FruitTransaction( + FruitTransaction.Operation.PURCHASE, null, 10 + ); + assertThrows(NullPointerException.class, + () -> purchaseOperationHandler.calculateOperation(fruitTransaction)); + } + + @Test + void processPurchaseOperation_negativeNumberOfFruits_notOk() { + Storage.STORAGE.put("banana", 20); + FruitTransaction fruitTransaction = new FruitTransaction( + FruitTransaction.Operation.PURCHASE, "banana", -100 + ); + assertThrows(RuntimeException.class, + () -> purchaseOperationHandler.calculateOperation(fruitTransaction)); + } + @Test void processPurchaseOperation_quantityMoreAmount_notOk() { Storage.STORAGE.put("banana", 20); diff --git a/src/test/java/core/basesyntax/handlers/ReturnOperationHandlerTest.java b/src/test/java/core/basesyntax/handlers/ReturnOperationHandlerTest.java index e68eb6f071..b6c7106b12 100644 --- a/src/test/java/core/basesyntax/handlers/ReturnOperationHandlerTest.java +++ b/src/test/java/core/basesyntax/handlers/ReturnOperationHandlerTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import core.basesyntax.db.Storage; import core.basesyntax.model.FruitTransaction; @@ -32,4 +33,24 @@ void processReturnOperation_ok() { int actualAmount = Storage.STORAGE.get("banana"); assertEquals(115, actualAmount); } + + @Test + void calculateOperation_negativeQuantity_notOk() { + FruitTransaction bananaTransaction = new FruitTransaction( + FruitTransaction.Operation.BALANCE, "banana", -100 + ); + assertThrows(RuntimeException.class, + () -> returnOperationHandler.calculateOperation(bananaTransaction) + ); + } + + @Test + void calculateOperation_nullFruit_notOk() { + FruitTransaction bananaTransaction = new FruitTransaction( + FruitTransaction.Operation.BALANCE, null, 100 + ); + assertThrows(NullPointerException.class, + () -> returnOperationHandler.calculateOperation(bananaTransaction) + ); + } } diff --git a/src/test/java/core/basesyntax/handlers/SupplyOperationHandlerTest.java b/src/test/java/core/basesyntax/handlers/SupplyOperationHandlerTest.java index e864227e13..e67184a212 100644 --- a/src/test/java/core/basesyntax/handlers/SupplyOperationHandlerTest.java +++ b/src/test/java/core/basesyntax/handlers/SupplyOperationHandlerTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import core.basesyntax.db.Storage; import core.basesyntax.model.FruitTransaction; @@ -32,4 +33,35 @@ void processSupply_ok() { int actualAmount = Storage.STORAGE.get("banana"); assertEquals(115, actualAmount); } + + @Test + void processSupply_negativeQuantity_notOk() { + FruitTransaction bananaTransaction = new FruitTransaction( + FruitTransaction.Operation.BALANCE, "banana", -100 + ); + assertThrows(RuntimeException.class, + () -> supplyOperationHandler.calculateOperation(bananaTransaction) + ); + } + + @Test + void calculateOperation_nullFruit_notOk() { + FruitTransaction bananaTransaction = new FruitTransaction( + FruitTransaction.Operation.BALANCE, null, 100 + ); + assertThrows(NullPointerException.class, + () -> supplyOperationHandler.calculateOperation(bananaTransaction) + ); + } + + @Test + void calculateOperation_nullOperationType_notOk() { + FruitTransaction bananaTransaction = new FruitTransaction( + null, "banana", 100 + ); + assertThrows(NullPointerException.class, + () -> supplyOperationHandler.calculateOperation(bananaTransaction) + ); + } + } diff --git a/src/test/java/core/basesyntax/services/DataProcessorServiceTest.java b/src/test/java/core/basesyntax/services/DataProcessorServiceTest.java index 7c9b3328bb..fb10dc1d93 100644 --- a/src/test/java/core/basesyntax/services/DataProcessorServiceTest.java +++ b/src/test/java/core/basesyntax/services/DataProcessorServiceTest.java @@ -47,4 +47,10 @@ void processData_invalidOperationType_notOk() { List data = List.of("buy,banana,-200", "b,apple,20", "s,banana,10"); assertThrows(RuntimeException.class, () -> dataProcessorService.processInputData(data)); } + + @Test + void processData_nonNumericQuantity_notOk() { + List data = List.of("b,banana,abc", "b,apple,abc", "s,banana,abc"); + assertThrows(RuntimeException.class, () -> dataProcessorService.processInputData(data)); + } } diff --git a/src/test/java/core/basesyntax/services/FileReaderServiceTest.java b/src/test/java/core/basesyntax/services/FileReaderServiceTest.java index dc2e6ba728..f26ab5bc0f 100644 --- a/src/test/java/core/basesyntax/services/FileReaderServiceTest.java +++ b/src/test/java/core/basesyntax/services/FileReaderServiceTest.java @@ -12,6 +12,7 @@ class FileReaderServiceTest { private static FileReaderService fileReaderService; private static final String VALID_FILE_PATH = "src/test/java/resources/test.csv"; private static final String INVALID_FILE_PATH = "src/test/java/resources/InvalidTest.csv"; + private static final String EMPTY_FILE_PATH = "src/test/java/resources/empty_file_csv"; @BeforeAll static void beforeAll() { @@ -29,6 +30,13 @@ void readData_existingFile_ok() { assertEquals(expected,actual); } + @Test + void readData_emptyFile_ok() { + List expected = List.of(); + List actual = fileReaderService.readFromFile(EMPTY_FILE_PATH); + assertEquals(expected, actual); + } + @Test void readData_notExistingFile_notOk() { assertThrows(RuntimeException.class, diff --git a/src/test/java/core/basesyntax/services/FileWriterServiceTest.java b/src/test/java/core/basesyntax/services/FileWriterServiceTest.java index d7dd9186e2..aff770c60c 100644 --- a/src/test/java/core/basesyntax/services/FileWriterServiceTest.java +++ b/src/test/java/core/basesyntax/services/FileWriterServiceTest.java @@ -38,4 +38,11 @@ void writeTo_invalidFilePath_notOk() { () -> fileWriterService.writeToFile(INVALID_FILE_PATH, report) ); } + + @Test + void writeTo_nullReport_notOk() { + assertThrows(RuntimeException.class, + () -> fileWriterService.writeToFile(INVALID_FILE_PATH, null) + ); + } } diff --git a/src/test/java/core/basesyntax/services/OperationProcessorTest.java b/src/test/java/core/basesyntax/services/OperationProcessorTest.java index bae77a988a..1ee809cea9 100644 --- a/src/test/java/core/basesyntax/services/OperationProcessorTest.java +++ b/src/test/java/core/basesyntax/services/OperationProcessorTest.java @@ -9,7 +9,7 @@ import core.basesyntax.handlers.SupplyOperationHandler; import core.basesyntax.model.FruitTransaction; import core.basesyntax.services.impl.OperationProcessorImpl; -import java.util.Collections; +import java.util.ArrayList; import java.util.List; import java.util.Map; import org.junit.jupiter.api.AfterEach; @@ -35,8 +35,9 @@ void tearDown() { } @Test - void processOperation_emptyList_notOk() { - assertDoesNotThrow(() -> operationProcessor.manageTransactions(Collections.emptyList())); + void processOperation_emptyList_Ok() { + List fruitTransactions = new ArrayList<>(); + assertDoesNotThrow(() -> operationProcessor.manageTransactions(fruitTransactions)); } @Test @@ -48,4 +49,5 @@ void processOperations_nonEmptyList_ok() { ); assertDoesNotThrow(() -> operationProcessor.manageTransactions(transactions)); } + } diff --git a/src/test/java/core/basesyntax/services/ReportCreatorServiceTest.java b/src/test/java/core/basesyntax/services/ReportCreatorServiceTest.java index 6d168cf4c1..03cbc2cf0d 100644 --- a/src/test/java/core/basesyntax/services/ReportCreatorServiceTest.java +++ b/src/test/java/core/basesyntax/services/ReportCreatorServiceTest.java @@ -35,4 +35,12 @@ void createReport_existingData_ok() { + "banana,10" + System.lineSeparator() + "apple,20" + System.lineSeparator(); assertEquals(expectedReport, reportCreatorService.createReport()); } + + @Test + void createReport_OneItem_Ok() { + Storage.STORAGE.put("banana", 10); + String expectedReport = "fruit,quantity" + System.lineSeparator() + + "banana,10" + System.lineSeparator(); + assertEquals(expectedReport,reportCreatorService.createReport()); + } } diff --git a/src/test/java/resources/empty_file_csv b/src/test/java/resources/empty_file_csv new file mode 100644 index 0000000000..e69de29bb2 From 22d1097b95462a23e4a6a88c5573b1676638c37a Mon Sep 17 00:00:00 2001 From: Dmytro Cherepov Date: Wed, 20 Sep 2023 13:49:29 +0300 Subject: [PATCH 4/6] added fixes --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 63566994ee..1f585a6fad 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,7 @@ LINE COVEREDRATIO - 0.8 + 0.8 @@ -97,7 +97,7 @@ - **/Main* + **/FruitShop* From 9872b2236c7408b9e5ff68d640a362a3af432ec8 Mon Sep 17 00:00:00 2001 From: Dmytro Cherepov Date: Mon, 25 Sep 2023 12:43:08 +0300 Subject: [PATCH 5/6] added fixes after review --- .../handlers/BalanceOperationHandlerTest.java | 11 ++++++----- .../handlers/PurchaseOperationHandlerTest.java | 13 +++++++------ .../handlers/ReturnOperationHandlerTest.java | 9 +++++---- .../handlers/SupplyOperationHandlerTest.java | 11 ++++++----- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/test/java/core/basesyntax/handlers/BalanceOperationHandlerTest.java b/src/test/java/core/basesyntax/handlers/BalanceOperationHandlerTest.java index 691b5a1af9..37765119f3 100644 --- a/src/test/java/core/basesyntax/handlers/BalanceOperationHandlerTest.java +++ b/src/test/java/core/basesyntax/handlers/BalanceOperationHandlerTest.java @@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import core.basesyntax.db.Storage; +import core.basesyntax.excteption.InvalidDataException; import core.basesyntax.model.FruitTransaction; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -24,7 +25,7 @@ void tearDown() { } @Test - void calculateOperation_ok() { + void addSomeFruit_BalanceOperation_Ok() { FruitTransaction bananaTransaction = new FruitTransaction( FruitTransaction.Operation.BALANCE, "banana", 120 ); @@ -40,17 +41,17 @@ void calculateOperation_ok() { } @Test - void calculateOperation_negativeQuantity_notOk() { + void addFruits_NegativeQuantity_notOk() { FruitTransaction bananaTransaction = new FruitTransaction( FruitTransaction.Operation.BALANCE, "banana", -100 ); - assertThrows(RuntimeException.class, + assertThrows(InvalidDataException.class, () -> balanceOperationHandler.calculateOperation(bananaTransaction) ); } @Test - void calculateOperation_nullFruit_notOk() { + void addFruits_nullFruit_notOk() { FruitTransaction bananaTransaction = new FruitTransaction( FruitTransaction.Operation.BALANCE, null, 100 ); @@ -60,7 +61,7 @@ void calculateOperation_nullFruit_notOk() { } @Test - void calculateOperation_nullOperationType_notOk() { + void addFruits_NullOperationType_notOk() { FruitTransaction bananaTransaction = new FruitTransaction( null, "banana", 100 ); diff --git a/src/test/java/core/basesyntax/handlers/PurchaseOperationHandlerTest.java b/src/test/java/core/basesyntax/handlers/PurchaseOperationHandlerTest.java index 90b9373e1f..180b415994 100644 --- a/src/test/java/core/basesyntax/handlers/PurchaseOperationHandlerTest.java +++ b/src/test/java/core/basesyntax/handlers/PurchaseOperationHandlerTest.java @@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import core.basesyntax.db.Storage; +import core.basesyntax.excteption.InvalidDataException; import core.basesyntax.model.FruitTransaction; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -24,7 +25,7 @@ void tearDown() { } @Test - void processPurchaseOperation_ok() { + void purchaseHandler_ValidData_ok() { Storage.STORAGE.put("banana", 100); FruitTransaction fruitTransaction = new FruitTransaction( FruitTransaction.Operation.PURCHASE, "banana", 70 @@ -35,7 +36,7 @@ void processPurchaseOperation_ok() { } @Test - void processPurchaseOperation_nullFruit_notOk() { + void purchaseHandler_nullFruit_notOk() { Storage.STORAGE.put("banana", 20); FruitTransaction fruitTransaction = new FruitTransaction( FruitTransaction.Operation.PURCHASE, null, 10 @@ -45,22 +46,22 @@ void processPurchaseOperation_nullFruit_notOk() { } @Test - void processPurchaseOperation_negativeNumberOfFruits_notOk() { + void purchaseHandler_NegativeQuantity_notOk() { Storage.STORAGE.put("banana", 20); FruitTransaction fruitTransaction = new FruitTransaction( FruitTransaction.Operation.PURCHASE, "banana", -100 ); - assertThrows(RuntimeException.class, + assertThrows(InvalidDataException.class, () -> purchaseOperationHandler.calculateOperation(fruitTransaction)); } @Test - void processPurchaseOperation_quantityMoreAmount_notOk() { + void purchaseHandler_quantityMoreAmount_notOk() { Storage.STORAGE.put("banana", 20); FruitTransaction fruitTransaction = new FruitTransaction( FruitTransaction.Operation.PURCHASE, "banana", 70 ); - assertThrows(RuntimeException.class, + assertThrows(InvalidDataException.class, () -> purchaseOperationHandler.calculateOperation(fruitTransaction)); } } diff --git a/src/test/java/core/basesyntax/handlers/ReturnOperationHandlerTest.java b/src/test/java/core/basesyntax/handlers/ReturnOperationHandlerTest.java index b6c7106b12..eeae6610d1 100644 --- a/src/test/java/core/basesyntax/handlers/ReturnOperationHandlerTest.java +++ b/src/test/java/core/basesyntax/handlers/ReturnOperationHandlerTest.java @@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import core.basesyntax.db.Storage; +import core.basesyntax.excteption.InvalidDataException; import core.basesyntax.model.FruitTransaction; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -24,7 +25,7 @@ void tearDown() { } @Test - void processReturnOperation_ok() { + void returnHandler_ValidData_ok() { Storage.STORAGE.put("banana", 15); FruitTransaction fruitTransaction = new FruitTransaction( FruitTransaction.Operation.RETURN, "banana", 100 @@ -35,17 +36,17 @@ void processReturnOperation_ok() { } @Test - void calculateOperation_negativeQuantity_notOk() { + void returnHandler_negativeQuantity_notOk() { FruitTransaction bananaTransaction = new FruitTransaction( FruitTransaction.Operation.BALANCE, "banana", -100 ); - assertThrows(RuntimeException.class, + assertThrows(InvalidDataException.class, () -> returnOperationHandler.calculateOperation(bananaTransaction) ); } @Test - void calculateOperation_nullFruit_notOk() { + void returnHandler_nullFruit_notOk() { FruitTransaction bananaTransaction = new FruitTransaction( FruitTransaction.Operation.BALANCE, null, 100 ); diff --git a/src/test/java/core/basesyntax/handlers/SupplyOperationHandlerTest.java b/src/test/java/core/basesyntax/handlers/SupplyOperationHandlerTest.java index e67184a212..95ff8c205a 100644 --- a/src/test/java/core/basesyntax/handlers/SupplyOperationHandlerTest.java +++ b/src/test/java/core/basesyntax/handlers/SupplyOperationHandlerTest.java @@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import core.basesyntax.db.Storage; +import core.basesyntax.excteption.InvalidDataException; import core.basesyntax.model.FruitTransaction; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; @@ -24,7 +25,7 @@ void tearDown() { } @Test - void processSupply_ok() { + void supplyHandler_ValidData_ok() { Storage.STORAGE.put("banana", 15); FruitTransaction fruitTransaction = new FruitTransaction( FruitTransaction.Operation.RETURN, "banana", 100); @@ -35,17 +36,17 @@ void processSupply_ok() { } @Test - void processSupply_negativeQuantity_notOk() { + void supplyHandler_NegativeQuantity_notOk() { FruitTransaction bananaTransaction = new FruitTransaction( FruitTransaction.Operation.BALANCE, "banana", -100 ); - assertThrows(RuntimeException.class, + assertThrows(InvalidDataException.class, () -> supplyOperationHandler.calculateOperation(bananaTransaction) ); } @Test - void calculateOperation_nullFruit_notOk() { + void supplyHandler_NullFruit_notOk() { FruitTransaction bananaTransaction = new FruitTransaction( FruitTransaction.Operation.BALANCE, null, 100 ); @@ -55,7 +56,7 @@ void calculateOperation_nullFruit_notOk() { } @Test - void calculateOperation_nullOperationType_notOk() { + void supplyHandler_NullOperationType_notOk() { FruitTransaction bananaTransaction = new FruitTransaction( null, "banana", 100 ); From a91d0e7e81e976ffc79769052d34392eb6a75c1a Mon Sep 17 00:00:00 2001 From: Dmytro Cherepov Date: Mon, 25 Sep 2023 12:47:15 +0300 Subject: [PATCH 6/6] added fixes --- .../core/basesyntax/handlers/PurchaseOperationHandler.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/core/basesyntax/handlers/PurchaseOperationHandler.java b/src/main/java/core/basesyntax/handlers/PurchaseOperationHandler.java index ce1125bac9..a9e787a865 100644 --- a/src/main/java/core/basesyntax/handlers/PurchaseOperationHandler.java +++ b/src/main/java/core/basesyntax/handlers/PurchaseOperationHandler.java @@ -8,6 +8,7 @@ public class PurchaseOperationHandler implements OperationHandler { @Override public void calculateOperation(FruitTransaction transaction) { + if (transaction.getQuantity() < 0) { throw new InvalidDataException("Negative quantity"); } else if (transaction.getFruit() == null) { @@ -17,7 +18,7 @@ public void calculateOperation(FruitTransaction transaction) { int quantity = transaction.getQuantity(); int purchaseResult = currentAmount - quantity; if (purchaseResult < 0) { - throw new RuntimeException("Not enough fruits in storage"); + throw new InvalidDataException("Not enough fruits in storage"); } Storage.STORAGE.put(transaction.getFruit(), purchaseResult); }