diff --git a/src/main/java/nl/knaw/dans/dvcli/action/BatchProcessor.java b/src/main/java/nl/knaw/dans/dvcli/action/BatchProcessor.java index 6068f09..ff18506 100644 --- a/src/main/java/nl/knaw/dans/dvcli/action/BatchProcessor.java +++ b/src/main/java/nl/knaw/dans/dvcli/action/BatchProcessor.java @@ -16,6 +16,7 @@ package nl.knaw.dans.dvcli.action; import lombok.Builder; +import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import java.util.List; @@ -34,17 +35,20 @@ public class BatchProcessor { /** * The labeled items to process. */ + @NonNull private final List> labeledItems; /** * The action to apply to each item. */ + @NonNull private final ThrowingFunction action; /** * The report to which the results of the actions are reported. */ - private final Report report; + @Builder.Default + private final Report report = new ConsoleReport<>(); /** * The delay in milliseconds between processing items. A delay of 0 or less means no delay. @@ -60,7 +64,7 @@ public void process() { log.info("Processing item {} of {}", ++i, labeledItems.size()); callAction(labeledItem.getFirst(), labeledItem.getSecond()); } - log.info("Finished batch processing"); + log.info("Finished batch processing of {} items", labeledItems.size()); } private void callAction(String label, I item) { diff --git a/src/test/java/nl/knaw/dans/dvcli/action/BatchProcessorTest.java b/src/test/java/nl/knaw/dans/dvcli/action/BatchProcessorTest.java index 06db35b..4abfd9d 100644 --- a/src/test/java/nl/knaw/dans/dvcli/action/BatchProcessorTest.java +++ b/src/test/java/nl/knaw/dans/dvcli/action/BatchProcessorTest.java @@ -89,7 +89,7 @@ BatchProcessor. builder() DEBUG Sleeping for 1 ms INFO Processing item 3 of 3 ok - INFO Finished batch processing + INFO Finished batch processing of 3 items """); assertThat(TestUtils.messagesOf(logged)) .containsExactly("INFO Starting batch processing", @@ -98,7 +98,7 @@ BatchProcessor. builder() "INFO Processing item 2 of 3", "DEBUG Sleeping for 1 ms", "INFO Processing item 3 of 3", - "INFO Finished batch processing"); + "INFO Finished batch processing of 3 items"); } @Test @@ -126,7 +126,7 @@ BatchProcessor. builder() DEBUG Sleeping for 1000 ms INFO Processing item 3 of 3 ok - INFO Finished batch processing + INFO Finished batch processing of 3 items """); } @@ -153,73 +153,80 @@ BatchProcessor. builder() ok INFO Processing item 3 of 3 ok - INFO Finished batch processing + INFO Finished batch processing of 3 items """); } @Test - public void batchProcessor_fails_fast_on_missing_report() { - var processor = BatchProcessor. builder() + public void batchProcessor_uses_a_default_report() { + BatchProcessor. builder() .labeledItems(List.of( - new Pair<>("A", Mockito.mock(DatasetApi.class)), - new Pair<>("B", Mockito.mock(DatasetApi.class)), - new Pair<>("C", Mockito.mock(DatasetApi.class)) + new Pair<>("X", Mockito.mock(DatasetApi.class)), + new Pair<>("Y", Mockito.mock(DatasetApi.class)), + new Pair<>("Z", Mockito.mock(DatasetApi.class)) )) .action(datasetApi -> "ok") - .build(); - assertThatThrownBy(processor::process) - .isInstanceOf(NullPointerException.class) - .hasMessage(""" - Cannot invoke "nl.knaw.dans.dvcli.action.Report.reportFailure(String, Object, java.lang.Exception)" because "this.report" is null"""); + .delay(0L) + .build() + .process(); - assertThat(stderr.toString()).isEqualTo(""); + assertThat(stderr.toString()).isEqualTo("X: OK. Y: OK. Z: OK. "); assertThat(stdout.toString()).isEqualTo(""" INFO Starting batch processing INFO Processing item 1 of 3 + ok + INFO Processing item 2 of 3 + ok + INFO Processing item 3 of 3 + ok + INFO Finished batch processing of 3 items """); } @Test - public void batchProcessor_does_not_fail_on_empty_list() { - var processor = BatchProcessor. builder() - .labeledItems(new ArrayList<>()) + public void batchProcessor_reports_empty_list() { + BatchProcessor. builder() + .labeledItems(List.of()) + .action(datasetApi -> "ok") .report(new ConsoleReport<>()) - .build(); - processor.process(); + .build() + .process(); assertThat(stderr.toString()).isEqualTo(""); + assertThat(stdout.toString()).isEqualTo(""" + INFO Starting batch processing + INFO Finished batch processing of 0 items + """); + assertThat(TestUtils.messagesOf(logged)).containsExactly( + "INFO Starting batch processing", + "INFO Finished batch processing of 0 items"); } @Test - public void batchProcessor_does_not_fail_fast_on_missing_action() { + public void batchProcessor_throws_on_missing_list() { var processor = BatchProcessor. builder() - .labeledItems(List.of( - new Pair<>("A", Mockito.mock(DatasetApi.class)), - new Pair<>("B", Mockito.mock(DatasetApi.class)), - new Pair<>("C", Mockito.mock(DatasetApi.class)) - )) - .report(new ConsoleReport<>()) - .build(); - processor.process(); + .action(datasetApi -> "ok") + .report(new ConsoleReport<>()); - assertThat(stderr.toString()).isEqualTo(""" - A: FAILED: Exception type = NullPointerException, message = Cannot invoke "nl.knaw.dans.dvcli.action.ThrowingFunction.apply(Object)" because "this.action" is null - B: FAILED: Exception type = NullPointerException, message = Cannot invoke "nl.knaw.dans.dvcli.action.ThrowingFunction.apply(Object)" because "this.action" is null - C: FAILED: Exception type = NullPointerException, message = Cannot invoke "nl.knaw.dans.dvcli.action.ThrowingFunction.apply(Object)" because "this.action" is null - """); + assertThatThrownBy(processor::build) + .isInstanceOf(NullPointerException.class) + .hasMessage("labeledItems is marked non-null but is null"); + + assertThat(stderr.toString()).isEqualTo(""); + assertThat(stdout.toString()).isEqualTo(""); + assertThat(TestUtils.messagesOf(logged)).containsExactly(); } @Test - public void batchProcessor_fails_fast_on_missing_list() { + public void batchProcessor_fails_fast_on_missing_action() { var processor = BatchProcessor. builder() - .action(datasetApi -> "ok") - .report(new ConsoleReport<>()) - .build(); - assertThatThrownBy(processor::process) + .labeledItems(List.of()); + assertThatThrownBy(processor::build) .isInstanceOf(NullPointerException.class) - .hasMessage(""" - Cannot invoke "java.util.List.iterator()" because "this.labeledItems" is null"""); + .hasMessage("action is marked non-null but is null"); assertThat(stderr.toString()).isEqualTo(""); + assertThat(stdout.toString()).isEqualTo(""); + assertThat(TestUtils.messagesOf(logged)).containsExactly(); } }