Skip to content
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

Expensereport java refactored #19

Open
wants to merge 6 commits into
base: solutions
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions expensereport-java/src/ReportPrinter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.nelkinda.training;

import java.io.PrintStream;
import java.util.List;

public class ReportPrinter {
private final ExpenseFormatter formatter;
private final PrintStream output;

public ReportPrinter(ExpenseFormatter formatter, PrintStream output) {
this.formatter = formatter;
this.output = output;
}

public void printReport(List<Expense> expenses) {
int total = 0;
int mealExpenses = 0;

output.println(formatter.formatHeader());

for (Expense expense : expenses) {
if (expense.type == ExpenseType.DINNER || expense.type == ExpenseType.BREAKFAST) {
mealExpenses += expense.amount;
}

output.println(formatter.format(expense));

total += expense.amount;
}

output.println(formatter.formatFooter(mealExpenses, total));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.nelkinda.training;

public class Expense {
public ExpenseType type;
public int amount;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.nelkinda.training;

public interface ExpenseFormatter {
String format(Expense expense);
String formatHeader();
String formatFooter(int mealExpenses, int totalExpenses);
}
Original file line number Diff line number Diff line change
@@ -1,50 +1,15 @@
package com.nelkinda.training;

import java.util.Date;
import java.util.List;

enum ExpenseType {
DINNER, BREAKFAST, CAR_RENTAL
}

class Expense {
ExpenseType type;
int amount;
}

public class ExpenseReport {
public void printReport(List<Expense> expenses) {
int total = 0;
int mealExpenses = 0;

System.out.println("Expenses " + new Date());
private final ReportPrinter printer;

for (Expense expense : expenses) {
if (expense.type == ExpenseType.DINNER || expense.type == ExpenseType.BREAKFAST) {
mealExpenses += expense.amount;
}

String expenseName = "";
switch (expense.type) {
case DINNER:
expenseName = "Dinner";
break;
case BREAKFAST:
expenseName = "Breakfast";
break;
case CAR_RENTAL:
expenseName = "Car Rental";
break;
}

String mealOverExpensesMarker = expense.type == ExpenseType.DINNER && expense.amount > 5000 || expense.type == ExpenseType.BREAKFAST && expense.amount > 1000 ? "X" : " ";

System.out.println(expenseName + "\t" + expense.amount + "\t" + mealOverExpensesMarker);

total += expense.amount;
}
public ExpenseReport(ReportPrinter printer) {
this.printer = printer;
}

System.out.println("Meal expenses: " + mealExpenses);
System.out.println("Total expenses: " + total);
public void printReport(List<Expense> expenses) {
printer.printReport(expenses);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.nelkinda.training;

public enum ExpenseType {
DINNER, BREAKFAST, CAR_RENTAL
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.nelkinda.training;

import java.io.PrintStream;
import java.util.List;

public class ReportPrinter {
private final ExpenseFormatter formatter;
private final PrintStream output;

public ReportPrinter(ExpenseFormatter formatter, PrintStream output) {
this.formatter = formatter;
this.output = output;
}

public void printReport(List<Expense> expenses) {
int total = 0;
int mealExpenses = 0;

output.println(formatter.formatHeader());

for (Expense expense : expenses) {
if (expense.type == ExpenseType.DINNER || expense.type == ExpenseType.BREAKFAST) {
mealExpenses += expense.amount;
}

output.println(formatter.format(expense));

total += expense.amount;
}

output.println(formatter.formatFooter(mealExpenses, total));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.nelkinda.training;

public class SimpleExpenseFormatter implements ExpenseFormatter {

@Override
public String format(Expense expense) {
String expenseName = switch (expense.type) {
case DINNER -> "dinner";
case BREAKFAST -> "breakfast";
case CAR_RENTAL -> "car rental";
};

String mealOverExpensesMarker = expense.type == ExpenseType.DINNER && expense.amount > 5000 ||
expense.type == ExpenseType.BREAKFAST && expense.amount > 1000 ? "X" : " ";

return String.format("%s %d %s", expenseName, expense.amount, mealOverExpensesMarker);
}

@Override
public String formatHeader() {
return "Expenses " + new java.util.Date();
}

@Override
public String formatFooter(int mealExpenses, int totalExpenses) {
return String.format("Meal expenses: %d\nTotal expenses: %d", mealExpenses, totalExpenses);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.nelkinda.training;

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class ExpenseReportStepDefinitions {
private List<Expense> expenses;
private ByteArrayOutputStream outputStream;
private ExpenseReport report;

@Given("the following expenses:")
public void the_following_expenses(List<List<String>> expenseData) {
expenses = new ArrayList<>();
for (List<String> row : expenseData) {
Expense expense = new Expense();
expense.type = ExpenseType.valueOf(row.get(0).toUpperCase());
expense.amount = Integer.parseInt(row.get(1));
expenses.add(expense);
}
}

@When("printing the report")
public void printing_the_report() {
outputStream = new ByteArrayOutputStream();
PrintStream originalOut = System.out;
System.setOut(new PrintStream(outputStream));

ExpenseFormatter formatter = new SimpleExpenseFormatter();
ReportPrinter printer = new ReportPrinter(formatter, System.out);
report = new ExpenseReport(printer);
report.printReport(expenses);

System.setOut(originalOut);
}

@Then("the report MUST look like this:")
public void the_report_must_look_like_this(String expectedOutput) {
String actualOutput = outputStream.toString().trim();
String currentDate = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy").format(new Date());
String expectedWithDate = expectedOutput.replace("<current date>", currentDate).trim();

assertEquals(expectedWithDate, actualOutput);
}
}
31 changes: 31 additions & 0 deletions expensereport-java/src/test/resources/ExpenseReport.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Feature: ExpenseReport

Scenario: single breakfast expense
Given the following expenses:
| Type | Amount |
| BREAKFAST | 100 |
When printing the report
Then the report MUST look like this:
"""
Expenses <current date>
breakfast 100
Meal expenses: 100
Total expenses: 100
"""

Scenario: multiple expenses with some exceeding limits
Given the following expenses:
| Type | Amount |
| BREAKFAST | 1200 |
| DINNER | 6000 |
| CAR_RENTAL | 3000 |
When printing the report
Then the report MUST look like this:
"""
Expenses <current date>
breakfast 1200 X
dinner 6000 X
car rental 3000
Meal expenses: 7200
Total expenses: 10200
"""