From b82eb25feb162ac8a00ea0bc979069e902070cf4 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Oct 2025 09:18:39 +0000 Subject: [PATCH 1/5] Improve GitHub Action workflow for PR tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split the PR test workflow into two jobs for better performance: - Fast test job that runs all tests and provides quick feedback - SonarQube analysis job that runs after tests pass Updated workflow name to reflect Kotlin project. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .github/workflows/maven-pr-builder.yml | 40 +++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/.github/workflows/maven-pr-builder.yml b/.github/workflows/maven-pr-builder.yml index 99ee85152962..e54ba40ba3dc 100644 --- a/.github/workflows/maven-pr-builder.yml +++ b/.github/workflows/maven-pr-builder.yml @@ -1,4 +1,4 @@ -name: Java PR Builder +name: Kotlin PR Tests on: pull_request_target: @@ -9,10 +9,42 @@ permissions: contents: read jobs: - build-and-analyze: + test: + name: Run Tests + runs-on: ubuntu-22.04 + steps: + + - name: Checkout Code + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: 'maven' + + - name: Cache local Maven repository + uses: actions/cache@v4 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + + # Some tests need screen access + - name: Install xvfb + run: sudo apt-get install -y xvfb + + - name: Build and Test + run: xvfb-run ./mvnw clean verify - name: Build on JDK 21 + sonar-analysis: + name: SonarQube Analysis runs-on: ubuntu-22.04 + needs: test steps: - name: Checkout Code @@ -33,7 +65,7 @@ jobs: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} restore-keys: | - ${{ runner.os }}-maven- + ${{ runner.os }}-maven- # Cache Sonar packages which are used to run analysis and collect metrics - name: Cache SonarCloud packages From 8fd2f4ad322f616fe91f0b17dd793526f6d31d8c Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Oct 2025 09:21:45 +0000 Subject: [PATCH 2/5] Remove presubmit.ai workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .github/workflows/presubmit.yml | 35 --------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 .github/workflows/presubmit.yml diff --git a/.github/workflows/presubmit.yml b/.github/workflows/presubmit.yml deleted file mode 100644 index cac1250b70e8..000000000000 --- a/.github/workflows/presubmit.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: Presubmit.ai - -permissions: - contents: read - pull-requests: write - issues: write - -on: - pull_request_target: # Handle forked repository PRs in the base repository context - types: [opened, synchronize] - pull_request_review_comment: # Handle review comments - types: [created] - -jobs: - review: - runs-on: ubuntu-latest - steps: - - name: Check required secrets - run: | - if [ -z "${{ secrets.LLM_API_KEY }}" ]; then - echo "Error: LLM_API_KEY secret is not configured" - exit 1 - fi - - - name: Check out PR code - uses: actions/checkout@v3 - with: - ref: ${{ github.event.pull_request.head.sha }} - - - name: Run AI Reviewer - uses: presubmit/ai-reviewer@latest - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - LLM_API_KEY: ${{ secrets.LLM_API_KEY }} - LLM_MODEL: "gemini-1.5-flash" From b2b205e7a8d5b02654e88cea44d01f5ba8e95289 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Oct 2025 12:14:56 +0000 Subject: [PATCH 3/5] Fix AppTest to call top-level main function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After converting App.kt to use a top-level main() function, the test was still calling App.main(emptyArray()) which doesn't exist. Updated to call the top-level main() function directly. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- visitor/src/test/java/com/iluwatar/visitor/AppTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/visitor/src/test/java/com/iluwatar/visitor/AppTest.kt b/visitor/src/test/java/com/iluwatar/visitor/AppTest.kt index 21b57adebfbb..ab0bf4a31910 100644 --- a/visitor/src/test/java/com/iluwatar/visitor/AppTest.kt +++ b/visitor/src/test/java/com/iluwatar/visitor/AppTest.kt @@ -31,6 +31,6 @@ import org.junit.jupiter.api.Test internal class AppTest { @Test fun shouldExecuteWithoutException() { - assertDoesNotThrow { App.main(emptyArray()) } + assertDoesNotThrow { main() } } } From dcfcf98fbf3eabafbaa3450f0cd13fa8cb0f4d13 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 30 Oct 2025 16:54:16 +0000 Subject: [PATCH 4/5] Fix Kotlin version to 2.2.21 (stable release) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pom.xml was configured with Kotlin 2.2.0, but the correct latest stable version is 2.2.21. This was causing build failures as Maven couldn't properly resolve the dependencies. Updated kotlin.version from 2.2.0 to 2.2.21. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c5c0102dc3f1..fc7250fd30ef 100644 --- a/pom.xml +++ b/pom.xml @@ -69,7 +69,7 @@ iluwatar_java-design-patterns ${project.artifactId} Java Design Patterns - 2.2.0 + 2.2.21 From be945da0972e643e33150c716f4e2e9a5d76c373 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 31 Oct 2025 05:09:12 +0000 Subject: [PATCH 5/5] Fix Mockito matcher issues in visitor tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed NullPointerException, UnfinishedVerificationException, and InvalidUseOfMatchersException in SergeantTest, CommanderTest, and SoldierTest. The issue was using Mockito's eq() matcher in Kotlin. In Kotlin, eq() returns null (to signal "use this matcher"), but Kotlin's null safety doesn't allow passing null to non-nullable parameters. Solution: Remove the eq() matcher and pass the unit object directly to verify(), since we have the actual instance: - Before: Mockito.verify(mockedVisitor).visit(eq(unit)) - After: Mockito.verify(mockedVisitor).visit(unit) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- visitor/src/test/java/com/iluwatar/visitor/CommanderTest.kt | 3 +-- visitor/src/test/java/com/iluwatar/visitor/SergeantTest.kt | 3 +-- visitor/src/test/java/com/iluwatar/visitor/SoldierTest.kt | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/visitor/src/test/java/com/iluwatar/visitor/CommanderTest.kt b/visitor/src/test/java/com/iluwatar/visitor/CommanderTest.kt index 1b9d0c60f52e..055755367988 100644 --- a/visitor/src/test/java/com/iluwatar/visitor/CommanderTest.kt +++ b/visitor/src/test/java/com/iluwatar/visitor/CommanderTest.kt @@ -25,11 +25,10 @@ package com.iluwatar.visitor import org.mockito.Mockito -import org.mockito.ArgumentMatchers.eq /** CommanderTest */ internal class CommanderTest : UnitTest({ children -> Commander(*children) }) { override fun verifyVisit(unit: Commander, mockedVisitor: UnitVisitor) { - Mockito.verify(mockedVisitor).visit(eq(unit)) + Mockito.verify(mockedVisitor).visit(unit) } } diff --git a/visitor/src/test/java/com/iluwatar/visitor/SergeantTest.kt b/visitor/src/test/java/com/iluwatar/visitor/SergeantTest.kt index cd437b9b3e1c..8abcdb907482 100644 --- a/visitor/src/test/java/com/iluwatar/visitor/SergeantTest.kt +++ b/visitor/src/test/java/com/iluwatar/visitor/SergeantTest.kt @@ -25,11 +25,10 @@ package com.iluwatar.visitor import org.mockito.Mockito -import org.mockito.ArgumentMatchers.eq /** SergeantTest */ internal class SergeantTest : UnitTest({ children -> Sergeant(*children) }) { override fun verifyVisit(unit: Sergeant, mockedVisitor: UnitVisitor) { - Mockito.verify(mockedVisitor).visit(eq(unit)) + Mockito.verify(mockedVisitor).visit(unit) } } diff --git a/visitor/src/test/java/com/iluwatar/visitor/SoldierTest.kt b/visitor/src/test/java/com/iluwatar/visitor/SoldierTest.kt index b6f1da19538f..78ab1117a0ad 100644 --- a/visitor/src/test/java/com/iluwatar/visitor/SoldierTest.kt +++ b/visitor/src/test/java/com/iluwatar/visitor/SoldierTest.kt @@ -25,11 +25,10 @@ package com.iluwatar.visitor import org.mockito.Mockito -import org.mockito.ArgumentMatchers.eq /** SoldierTest */ internal class SoldierTest : UnitTest({ children -> Soldier(*children) }) { override fun verifyVisit(unit: Soldier, mockedVisitor: UnitVisitor) { - Mockito.verify(mockedVisitor).visit(eq(unit)) + Mockito.verify(mockedVisitor).visit(unit) } }