From aabcbe370069c0f61ee11fb335ca89f96a76b009 Mon Sep 17 00:00:00 2001 From: Luis <1105281+lpenap@users.noreply.github.com> Date: Wed, 16 Sep 2026 15:15:27 -0300 Subject: [PATCH] Cover remaining gaps and stop excluding tested classes from JaCoCo Add tests for the unknown product type in ProductFactory, the "unhandled" end of the handler chain, GuiAppender attaching itself to the root logger, and Producer stopping when interrupted. Producer now restores the interrupt flag and returns instead of swallowing the interruption. Remove the JaCoCo excludes for the pattern ExampleRunner classes and the two properties classes, which already have full test coverage. Reported scope grows from 342 to 673 instructions at 100% instruction and branch coverage. Co-Authored-By: Claude Fable 5.1 --- pom.xml | 3 --- .../constructs/producerconsumer/Producer.java | 2 ++ .../constructs/app/ui/GuiAppenderTests.java | 21 +++++++++++++++++++ .../chainofresponsibility/ChainTests.java | 17 +++++++++++++++ .../constructs/factory/FactoryTests.java | 7 +++++++ .../producerconsumer/ProducerTests.java | 17 +++++++++++++++ 6 files changed, 64 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 9ed37aa..69688d2 100644 --- a/pom.xml +++ b/pom.xml @@ -108,15 +108,12 @@ - **/*ExampleRunner* **/AppCommandLineRunner* **/ExamplesCommandLineRunner* **/ProducerConsumerExampleRunner* **/Consumer* **/JavaPatternsAndConstructsApplication* **/MainWindow* - **/Messages* - **/ApplicationProperties* **/HyperlinkMouseListener* **/ObservableAbstract* diff --git a/src/main/java/com/penapereira/example/constructs/producerconsumer/Producer.java b/src/main/java/com/penapereira/example/constructs/producerconsumer/Producer.java index 20e174a..8295a34 100644 --- a/src/main/java/com/penapereira/example/constructs/producerconsumer/Producer.java +++ b/src/main/java/com/penapereira/example/constructs/producerconsumer/Producer.java @@ -16,6 +16,8 @@ public void run() { try { queue.put(i); } catch (InterruptedException finish) { + Thread.currentThread().interrupt(); + return; } } } diff --git a/src/test/java/com/penapereira/example/constructs/app/ui/GuiAppenderTests.java b/src/test/java/com/penapereira/example/constructs/app/ui/GuiAppenderTests.java index 4d58ec2..dc2b178 100644 --- a/src/test/java/com/penapereira/example/constructs/app/ui/GuiAppenderTests.java +++ b/src/test/java/com/penapereira/example/constructs/app/ui/GuiAppenderTests.java @@ -1,10 +1,14 @@ package com.penapereira.example.constructs.app.ui; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.awt.EventQueue; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.spi.LoggingEvent; @@ -25,4 +29,21 @@ void appendsMessageToOutputSink() throws Exception { assertEquals("test message" + System.lineSeparator(), output.toString()); } + + @Test + void attachesItselfToRootLoggerWhenInitialized() throws Exception { + GuiAppender appender = new GuiAppender(text -> {}); + ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory + .getLogger(Logger.ROOT_LOGGER_NAME); + assertFalse(root.isAttached(appender)); + try { + appender.afterPropertiesSet(); + + assertTrue(appender.isStarted()); + assertTrue(root.isAttached(appender)); + } finally { + root.detachAppender(appender); + appender.stop(); + } + } } diff --git a/src/test/java/com/penapereira/example/constructs/chainofresponsibility/ChainTests.java b/src/test/java/com/penapereira/example/constructs/chainofresponsibility/ChainTests.java index ae4b36d..cf59a14 100644 --- a/src/test/java/com/penapereira/example/constructs/chainofresponsibility/ChainTests.java +++ b/src/test/java/com/penapereira/example/constructs/chainofresponsibility/ChainTests.java @@ -17,4 +17,21 @@ void chainProcessesNumbers() { assertEquals("zero", negative.handle(0)); assertEquals("positive", negative.handle(5)); } + + @Test + void requestNobodyHandlesIsReportedAsUnhandled() { + Handler negative = new NegativeHandler(); + Handler zero = new ZeroHandler(); + negative.setNext(zero); + + assertEquals("unhandled", negative.handle(5)); + } + + @Test + void lastHandlerWithoutNextReturnsUnhandled() { + Handler positive = new PositiveHandler(); + + assertEquals("positive", positive.handle(1)); + assertEquals("unhandled", positive.handle(-1)); + } } diff --git a/src/test/java/com/penapereira/example/constructs/factory/FactoryTests.java b/src/test/java/com/penapereira/example/constructs/factory/FactoryTests.java index e77b299..7186594 100644 --- a/src/test/java/com/penapereira/example/constructs/factory/FactoryTests.java +++ b/src/test/java/com/penapereira/example/constructs/factory/FactoryTests.java @@ -12,4 +12,11 @@ void factoryCreatesConcreteProducts() { assertEquals("Concrete Product A", a.name()); assertEquals("Concrete Product B", b.name()); } + + @Test + void factoryRejectsUnknownType() { + ProductFactory factory = new ProductFactory(); + IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> factory.createProduct("C")); + assertEquals("Unknown type: C", ex.getMessage()); + } } diff --git a/src/test/java/com/penapereira/example/constructs/producerconsumer/ProducerTests.java b/src/test/java/com/penapereira/example/constructs/producerconsumer/ProducerTests.java index f95e11e..6267953 100644 --- a/src/test/java/com/penapereira/example/constructs/producerconsumer/ProducerTests.java +++ b/src/test/java/com/penapereira/example/constructs/producerconsumer/ProducerTests.java @@ -20,4 +20,21 @@ void producerAddsElements() throws InterruptedException { assertEquals(2, queue.take()); assertEquals(3, queue.take()); } + + @Test + void producerStopsWhenInterrupted() throws InterruptedException { + BlockingQueue queue = new LinkedBlockingDeque<>(1); + Thread t = new Thread(new Producer(queue)); + t.start(); + while (queue.isEmpty()) { + Thread.onSpinWait(); + } + + t.interrupt(); + t.join(5_000); + + assertFalse(t.isAlive()); + assertEquals(1, queue.size()); + assertEquals(1, queue.take()); + } }