-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
hw done #1083
base: main
Are you sure you want to change the base?
hw done #1083
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job! But firstly let’s fix some issues with the main solution ;)
private FruitTransaction.Operation mapOperation(String code) { | ||
return switch (code) { | ||
case "b" -> FruitTransaction.Operation.BALANCE; | ||
case "s" -> FruitTransaction.Operation.SUPPLY; | ||
case "p" -> FruitTransaction.Operation.PURCHASE; | ||
case "r" -> FruitTransaction.Operation.RETURN; | ||
default -> throw new IllegalArgumentException("Unknown operation code: " + code); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't use switch case here, it will be difficult for you to maintain it in the future. Instead, add the following method to the Operation class:
public static Operation getOperation(String code) {
for (Operation value : Operation.values()) {
if (value.getCode().equals(code)) {
return value;
}
}
throw new IllegalArgumentException(code + " operation doesn't exist.");
}
public List<FruitTransaction> convertToTransaction(List<String> data) { | ||
List<FruitTransaction> convertedTransaction = new ArrayList<>(); | ||
for (int i = 1; i < data.size(); i++) { // Skip header | ||
String[] parts = data.get(i).split(","); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make separator and other magic numbers constant field
@Override | ||
public String getReport() { | ||
if (Storage.fruits.isEmpty()) { | ||
return "No records to report"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better throw exception
} | ||
StringBuilder report = new StringBuilder(); | ||
for (Map.Entry<String, Integer> entry : Storage.fruits.entrySet()) { | ||
report.append(entry.getKey()).append(",").append(entry.getValue()).append("\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make separator constant field and use System.lineseparator() instead \n
public OperationHandler getHandler(FruitTransaction.Operation operation) { | ||
OperationHandler handler = operationHandlerMap.get(operation); | ||
if (handler == null) { | ||
throw new NullPointerException("No handler found for operation: " + operation); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better throw IllegalArgumentException or general RuntimeException
} | ||
|
||
public enum Operation { | ||
BALANCE, SUPPLY, PURCHASE, RETURN |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BALANCE, SUPPLY, PURCHASE, RETURN | |
BALANCE("b")... |
use values
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job overall!
- use src/test/resources for testing
Map<FruitTransaction.Operation, OperationHandler> operationHandlers = new HashMap<>(); | ||
operationHandlers.put(FruitTransaction.Operation.BALANCE, new BalanceOperation()); | ||
operationHandlers.put(FruitTransaction.Operation.PURCHASE, new PurchaseOperation()); | ||
operationHandlers.put(FruitTransaction.Operation.RETURN, new ReturnOperation()); | ||
operationHandlers.put(FruitTransaction.Operation.SUPPLY, new SupplyOperation()); | ||
OperationStrategy operationStrategy = new OperationStrategyImpl(operationHandlers); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use Map.of for brevity in such cases
} | ||
|
||
@Test | ||
void converter_testConverterToTransactions_ok() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void converter_testConverterToTransactions_ok() { | |
void converter_validTransactions_ok() { |
second part is about given conditions
FruitTransaction actual = actualTransaction.get(i); | ||
|
||
Assertions.assertEquals(expected.getOperation(), actual.getOperation(), | ||
"Операції не збігаються"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't use anything but english in code
} catch (IOException e) { | ||
Assertions.fail("Failed to create test directory"); | ||
} finally { | ||
try { | ||
Files.deleteIfExists(directory); | ||
} catch (IOException e) { | ||
Assertions.fail("Failed to delete test directory"); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's better to keep our tests clean if possible, move cleanup handling to afterEach if needed, or loop up how to create temp files (like Files.createTempFile)
If exception is thrown, test will fail anyway
new FruitTransaction(FruitTransaction.Operation.SUPPLY, "apple", 50), | ||
new FruitTransaction(FruitTransaction.Operation.PURCHASE, "banana", 10) | ||
); | ||
Assertions.assertEquals(expectedTransaction.size(), actualTransaction.size(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use static import for assertions
} | ||
|
||
@Test | ||
void converter_testInvalidDataToConvert_notOk() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use the same naming convetion for all test method0s. Please, check everywhere
void converter_testInvalidDataToConvert_notOk() { | |
void convertToTransaction_invalidDataToConvert_notOk() { |
} | ||
|
||
@Test | ||
void converter_validTransactions_ok() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void converter_validTransactions_ok() { | |
void convertToTransaction_validTransactions_ok() { |
@Test | ||
void readFromFile_validFile_ok() throws IOException { | ||
String testFilePath = "src/main/resources/testFile.csv"; | ||
String fileContent = "type,fruit,quantity\nb,banana,20\ns,apple,50"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use text block to make this line more readable
} catch (IOException e) { | ||
Assertions.fail("Failed to create temporary directory", e); | ||
} finally { | ||
if (tempDirectory != null) { | ||
try { | ||
Files.deleteIfExists(tempDirectory); | ||
} catch (IOException e) { | ||
Assertions.fail("Failed to delete temporary directory", e); | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move it to the method with @AfterEach
annotation, like you did in FileWriterTest
Assertions.assertThrows(IllegalArgumentException.class, | ||
() -> operationStrategy.getHandler(null), | ||
"IllegalArgumentException."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's check error message content
@Test | ||
void operationStrategy_returnsCorrectHandler_ok() { | ||
OperationHandler handler = operationStrategy.getHandler(FruitTransaction.Operation.SUPPLY); | ||
|
||
Assertions.assertTrue(handler instanceof SupplyOperation, | ||
"Handler for SUPPLY should be of type SupplyOperation."); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's do the same for other handlers
|
||
@Test | ||
void reportGenerator_EmptyStorage_notOk() { | ||
Assertions.assertThrows(RuntimeException.class, () -> reportGenerator.getReport()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
new FruitTransaction( | ||
FruitTransaction.Operation.PURCHASE, "banana", 20) | ||
); | ||
Assertions.assertThrows(IllegalArgumentException.class, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
No description provided.