diff --git a/src/main/java/space/kklochko/simple_jbdd/tests/reports/CLIReporter.java b/src/main/java/space/kklochko/simple_jbdd/tests/reports/CLIReporter.java new file mode 100644 index 0000000..871019c --- /dev/null +++ b/src/main/java/space/kklochko/simple_jbdd/tests/reports/CLIReporter.java @@ -0,0 +1,95 @@ +package space.kklochko.simple_jbdd.tests.reports; + +import space.kklochko.simple_jbdd.tests.factories.meta.AbstractTestCommandMetaDataFactory; +import space.kklochko.simple_jbdd.tests.reports.fmt.AbstractTestReportFormatter; + +import java.util.AbstractMap; +import java.util.ArrayList; +import org.apache.commons.lang3.StringUtils; + +public class CLIReporter extends AbstractReporter { + final int terminalWidth = 80; + + public CLIReporter(ArrayList> metadata, AbstractTestReportFormatter formatter) { + super(metadata, formatter); + } + + public void report() { + ArrayList> testData = format(); + ArrayList> failedTestData = getFailedTests(testData); + int passed = count(testData, true); + int failed = count(testData, false); + + System.out.printf("%s\n", center(" Tests ")); + printTests(testData); + + if(failed != 0) { + System.out.printf("\n%s\n", center(" Errors ")); + printTests(failedTestData); + } + + System.out.printf("\n%s\n", center(" Summary ")); + System.out.print(summary(passed, failed)); + } + + public ArrayList> format() { + ArrayList> data = new ArrayList<>(); + + for(var pair : getMetadata()) { + boolean isPassed = pair.getValue(); + + getFormatter().setTestMetaData(pair.getKey().create()); + getFormatter().setPassed(isPassed); + + data.add(new AbstractMap.SimpleEntry<>(getFormatter().format(), isPassed)); + } + + return data; + } + + public ArrayList> getFailedTests(ArrayList> testData) { + ArrayList> failed = new ArrayList<>(); + + for(var pair : testData) { + boolean isPassed = pair.getValue(); + + if(isPassed) continue; + + failed.add(pair); + } + + return failed; + } + + public int count(ArrayList> testData, boolean isPassedStatus) { + int count = 0; + + for(var pair : testData) { + boolean isPassed = pair.getValue(); + + if(isPassed == isPassedStatus) + count++; + } + + return count; + } + + public void printTests(ArrayList> testData) { + for(var pair : testData) { + System.out.print(pair.getKey()); + } + } + + public String center(String content) { + return StringUtils.center(content, 80, '='); + } + + public String summary(int passed, int failed) { + int all = passed + failed; + double passedPercent = (double) passed / (double) all * 100.0; + double failedPercent = (double) failed / (double) all * 100.0; + + return String.format("Ran %d tests.\nPassed: %d (%.2f%%)\nFailed: %d (%.2f%%)\n", all, passed, passedPercent, failed, failedPercent); + } +} + diff --git a/src/test/groovy/space/kklochko/simple_jbdd/tests/reports/CLIReporterFormatMethodSpec.groovy b/src/test/groovy/space/kklochko/simple_jbdd/tests/reports/CLIReporterFormatMethodSpec.groovy new file mode 100644 index 0000000..5bbb94d --- /dev/null +++ b/src/test/groovy/space/kklochko/simple_jbdd/tests/reports/CLIReporterFormatMethodSpec.groovy @@ -0,0 +1,72 @@ +package space.kklochko.simple_jbdd.tests.reports + +import space.kklochko.simple_jbdd.tests.factories.meta.AbstractTestCommandMetaDataFactory +import space.kklochko.simple_jbdd.tests.reports.fmt.AbstractTestReportFormatter +import space.kklochko.simple_jbdd.tests.reports.fmt.SimpleTestReportFormatter +import spock.lang.Narrative +import spock.lang.Specification +import spock.lang.Subject +import spock.lang.Title + +@Narrative("""The reporter must generate a report in the same format, so +those tests check if the reporter generate it right. +""") +@Title("Unit tests for CLIReporter.format()") +class CLIReporterFormatMethodSpec extends Specification { + private metaData + + def setup() { + def factory = Mock(AbstractTestCommandMetaDataFactory) { + create() >> [ + new AbstractMap.SimpleEntry<>("Title", "A simple test"), + new AbstractMap.SimpleEntry<>("Then", "Then block") + ] + } + + def metaData = [ + new AbstractMap.SimpleEntry<>(factory, true), + new AbstractMap.SimpleEntry<>(factory, false) + ] + + this.metaData = metaData + } + + def "Format function use formatter twice."() { + given: "I have a formatter" + def formatter = Mock(AbstractTestReportFormatter) + + and: "I have a reporter" + @Subject + def reporter = new CLIReporter(metaData, formatter) + + when: "Generate the summary format" + def formattedTestData = reporter.format() + + then: "The methods must called 2 times" + 2 * formatter.format() + 2 * formatter.setPassed(_) + 2 * formatter.setTestMetaData(_) + + and: "The data must have 2 elements" + 2 == formattedTestData.size() + } + + def "Format function returns the formatted data."() { + given: "I have a formatter" + def formatter = new SimpleTestReportFormatter() + + and: "I have a reporter" + @Subject + def reporter = new CLIReporter(metaData, formatter) + + when: "Generate the summary format" + def formattedTestData = reporter.format() + + then: "The format must have not null values" + formattedTestData.every({ it.getKey() != null }) + + and: "The data must have 2 elements" + 2 == formattedTestData.size() + } +} + diff --git a/src/test/groovy/space/kklochko/simple_jbdd/tests/reports/CLIReporterSpec.groovy b/src/test/groovy/space/kklochko/simple_jbdd/tests/reports/CLIReporterSpec.groovy new file mode 100644 index 0000000..55280d8 --- /dev/null +++ b/src/test/groovy/space/kklochko/simple_jbdd/tests/reports/CLIReporterSpec.groovy @@ -0,0 +1,77 @@ +package space.kklochko.simple_jbdd.tests.reports + +import space.kklochko.simple_jbdd.tests.factories.meta.AbstractTestCommandMetaDataFactory +import space.kklochko.simple_jbdd.tests.reports.fmt.AbstractTestReportFormatter +import space.kklochko.simple_jbdd.tests.reports.fmt.SimpleTestReportFormatter +import spock.lang.Narrative +import spock.lang.Specification +import spock.lang.Subject +import spock.lang.Title + +@Narrative("""The reporter must generate a report in the same format, so +those tests check if the reporter generate it right. +""") +@Title("Unit tests for CLIReporter") +class CLIReporterSpec extends Specification { + def "Function, getFailedTest, returns the data of failed tests."() { + given: "I have a reporter" + @Subject + def reporter = new CLIReporter(null, null) + + and: "I have a testData" + def passedTestPair = new AbstractMap.SimpleEntry<>("Passed", true) + def failedTestPair = new AbstractMap.SimpleEntry<>("Failed", false) + def testData = Collections.nCopies(countPassed, passedTestPair) + Collections.nCopies(countFailed, failedTestPair) + + when: "Generate the summary format" + def failedTestData = reporter.getFailedTests(testData) + + then: "The format must be the same" + failedTestData.every({ it.getKey() == "Failed" && it.getValue() == false}) + expectedFailedCount == failedTestData.size() + + where: "Possible variants of tests" + countPassed | countFailed || expectedFailedCount + 5 | 10 || 10 + } + + def "Count function returns the count of passed or failed tests."() { + given: "I have a reporter" + @Subject + def reporter = new CLIReporter(null, null) + + and: "I have a testData" + def passedTestPair = new AbstractMap.SimpleEntry<>("Passed", true) + def failedTestPair = new AbstractMap.SimpleEntry<>("Failed", false) + def testData = Collections.nCopies(countPassed, passedTestPair) + Collections.nCopies(countFailed, failedTestPair) + + when: "Generate the summary format" + def count = reporter.count(testData, isPassed) + + then: "The format must be the same" + expectedCount == count + + where: "Possible variants of tests" + countPassed | countFailed | isPassed || expectedCount + 10 | 20 | true || 10 + 10 | 20 | false || 20 + } + + def "Summary format."() { + given: "I have a reporter" + @Subject + def reporter = new CLIReporter(null, null) + + when: "Generate the summary format" + def format = reporter.summary(passed, failed) + + then: "The format must be the same" + expectedFormat == format + + where: "Possible variants of tests" + passed | failed || expectedFormat + 10 | 20 || "Ran 30 tests.\nPassed: 10 (33.33%)\nFailed: 20 (66.67%)\n" + 10 | 10 || "Ran 20 tests.\nPassed: 10 (50.00%)\nFailed: 10 (50.00%)\n" + } +} +