Skip to content

Port PR #114: Fix stall upgrade logic and test stability#115

Merged
candour merged 2 commits into
mainfrom
port-pr-114-fixes-7969685778257572278
May 2, 2026
Merged

Port PR #114: Fix stall upgrade logic and test stability#115
candour merged 2 commits into
mainfrom
port-pr-114-fixes-7969685778257572278

Conversation

@candour

@candour candour commented May 2, 2026

Copy link
Copy Markdown
Owner

This PR ports the remaining logic and stability fixes from the original PR #114 (#114) to resolve merge conflicts and synchronize the codebase with the intended upgrade scaling and test reliability improvements.

Key changes include:

  1. MainViewModel.kt: Changed gameJob visibility to internal for test control, added validation for specific upgrades, and ensured the seeded random instance is used for deterministic test results.
  2. LegendaryNames.kt: Added the "Boost" category prefixes and suffixes for Bak Kut Teh stalls.
  3. Unit Tests: Updated BossWaveLogicTest, KitchelinBonusTest, LegendaryNamingTest, and MilestoneBoostTest to match the current game state and ensure deterministic, stable runs by cancelling the background game loop in setup.

All tests passed successfully.


PR created automatically by Jules for task 7969685778257572278 started by @candour

Summary by CodeRabbit

  • New Features

    • Added legendary items in a new "Boost" category, expanding legendary name variety.
  • Bug Fixes

    • More reliable upgrade stat selection by improving randomization and validation.
    • Corrected milestone bonus calculations for accurate progression rewards.
    • Strengthened upgrade validation to prevent invalid upgrade outcomes.

- Centralized stall upgrade logic to ensure UI descriptions match gameplay scaling.
- Added "Boost" category to the legendary naming system for Bak Kut Teh stalls.
- Improved unit test stability by explicitly managing the ViewModel's game loop (cancelling gameJob).
- Resolved logical errors and timeouts in KitchelinBonusTest and BossWaveLogicTest.
- Updated MilestoneBoostTest and LegendaryNamingTest to reflect current scaling rules and use deterministic upgrade methods.
- Validated specificStat in MainViewModel.kt to prevent invalid state changes.

Co-authored-by: candour <4670475+candour@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai

coderabbitai Bot commented May 2, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Precomputes available upgrade stats and validates specific stat choices in MainViewModel, switches non-specific stat selection to the view model’s seeded RNG, widens gameJob visibility, adds a "Boost" category to legendary name maps, and updates tests to use a seeded Random and cancel gameJob during setup.

Changes

Upgrade Selection Refactoring & Test Adjustments

Layer / File(s) Summary
Constructor / RNG surface
app/src/main/java/com/messark/hawker/MainViewModel.kt
random exposed as a constructor property (seedable RNG) so upgrade-selection can use a deterministic RNG.
Visibility
app/src/main/java/com/messark/hawker/MainViewModel.kt
gameJob visibility changed from private var to internal var.
Core Upgrade Logic
app/src/main/java/com/messark/hawker/MainViewModel.kt
applyUpgrade now computes availableStats up front, validates specificStat membership (returns unchanged state if invalid), and selects non-specific stat via availableStats.random(this@MainViewModel.random).
Test construction & cleanup
app/src/test/java/com/messark/hawker/... (BossWaveLogicTest.kt, KitchelinBonusTest.kt, LegendaryNamingTest.kt, MilestoneBoostTest.kt, MainViewModelTest.kt, StallStatsTest.kt, UndeadEnemyTest.kt, ...)
Tests now instantiate MainViewModel with kotlin.random.Random(42) where applicable and immediately call viewModel.gameJob?.cancel() in setup to ensure background job cleanup.
Test upgrade invocation changes
app/src/test/java/com/messark/hawker/LegendaryNamingTest.kt, MilestoneBoostTest.kt
Upgrade loops changed from upgradeStall() to upgradeStallRandomly() to exercise seeded RNG-based selection.
Test flow & assertions
app/src/test/java/com/messark/hawker/KitchelinBonusTest.kt, MilestoneBoostTest.kt
Several tests simplify tick/advance logic (collapse into single updateGame(1000L)), update enemy/projectile setup, and adjust expected values to align with registry baselines and RNG-driven behavior; removed an unused import.

Boost Legendary Naming Extension

Layer / File(s) Summary
Data Extension
app/src/main/java/com/messark/hawker/utils/LegendaryNames.kt
Added "Boost" entries to both suffixes and prefixes maps so getRandomSuffix/getRandomPrefix can return Boost-category strings. No other API signatures changed.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: porting PR #114 and fixing stall upgrade logic and test stability, which directly aligns with the changeset's core objectives.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch port-pr-114-fixes-7969685778257572278

Review rate limit: 9/10 reviews remaining, refill in 6 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented May 2, 2026

Copy link
Copy Markdown

Build Successful! 🚀

Download APK

Note: This link will be removed when the PR is closed.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
app/src/test/java/com/messark/hawker/BossWaveLogicTest.kt (1)

29-42: ⚠️ Potential issue | 🟠 Major

Add Dispatchers.resetMain() teardown to prevent cross-test leakage.

Line 31 overrides Dispatchers.Main, but this class never restores it. That can destabilize unrelated tests executed afterward.

Suggested fix
 import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.resetMain
 import kotlinx.coroutines.test.advanceUntilIdle
 import kotlinx.coroutines.test.runTest
 import kotlinx.coroutines.test.setMain
+import org.junit.After
@@
 class BossWaveLogicTest {
@@
     `@Before`
     fun setup() {
         Dispatchers.setMain(testDispatcher)
@@
         viewModel = MainViewModel(application, settingsRepository, gameStateRepository)
         viewModel.gameJob?.cancel()
     }
+
+    `@After`
+    fun tearDown() {
+        Dispatchers.resetMain()
+    }
app/src/test/java/com/messark/hawker/LegendaryNamingTest.kt (1)

22-26: ⚠️ Potential issue | 🟠 Major

Add @After teardown to reset the Main dispatcher.

This test sets Dispatchers.Main in setup without resetting it, which can bleed scheduler state into subsequent tests and cause flakiness. Import resetMain and @After, then add a teardown method.

Suggested fix
 import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.resetMain
 import kotlinx.coroutines.test.setMain
 import org.junit.Assert.*
+import org.junit.After
 import org.junit.Before
 import org.junit.Test
 
@@ -23,6 +26,11 @@ class LegendaryNamingTest {
     `@Before`
     fun setup() {
         Dispatchers.setMain(testDispatcher)
     }
+
+    `@After`
+    fun tearDown() {
+        Dispatchers.resetMain()
+    }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 89078c47-739f-40e8-92ac-8baf171010a7

📥 Commits

Reviewing files that changed from the base of the PR and between 9d83172 and 5a67b1b.

📒 Files selected for processing (6)
  • app/src/main/java/com/messark/hawker/MainViewModel.kt
  • app/src/main/java/com/messark/hawker/utils/LegendaryNames.kt
  • app/src/test/java/com/messark/hawker/BossWaveLogicTest.kt
  • app/src/test/java/com/messark/hawker/KitchelinBonusTest.kt
  • app/src/test/java/com/messark/hawker/LegendaryNamingTest.kt
  • app/src/test/java/com/messark/hawker/MilestoneBoostTest.kt

Comment thread app/src/main/java/com/messark/hawker/MainViewModel.kt
@candour
candour enabled auto-merge (squash) May 2, 2026 07:53
- Ported upgrade logic synchronization and legendary naming from PR #114.
- Made RNG injectable in MainViewModel constructor with a default value.
- Updated all unit tests to inject a fixed-seed Random(42) for determinism.
- Changed gameJob visibility to internal and cancelled it in test setups.
- Validated specificStat in applyUpgrade.
- Verified all unit tests pass.

Co-authored-by: candour <4670475+candour@users.noreply.github.com>
@github-actions

github-actions Bot commented May 2, 2026

Copy link
Copy Markdown

Build Successful! 🚀

Download APK

Note: This link will be removed when the PR is closed.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
app/src/main/java/com/messark/hawker/MainViewModel.kt (1)

42-42: ⚡ Quick win

Limit gameJob mutability while keeping test access.

internal var allows same-module reassignment; tests only need to read/cancel. Consider private set to preserve lifecycle ownership in MainViewModel.

Suggested change
-    internal var gameJob: Job? = null
+    internal var gameJob: Job? = null
+        private set
app/src/test/java/com/messark/hawker/BossWaveLogicTest.kt (1)

29-42: ⚡ Quick win

Add a teardown to reset Dispatchers.Main.

This test sets Dispatchers.Main but doesn’t restore it, which can bleed into other tests in the same run.

Suggested change
+import kotlinx.coroutines.test.resetMain
+import org.junit.After
@@
 class BossWaveLogicTest {
@@
     `@Before`
     fun setup() {
         Dispatchers.setMain(testDispatcher)
@@
         viewModel = MainViewModel(application, settingsRepository, gameStateRepository, kotlin.random.Random(42))
         viewModel.gameJob?.cancel()
     }
+
+    `@After`
+    fun tearDown() {
+        Dispatchers.resetMain()
+    }

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1f40fbea-853e-4ab5-ab55-f5fc12c2d6db

📥 Commits

Reviewing files that changed from the base of the PR and between 5a67b1b and 14eeec7.

📒 Files selected for processing (8)
  • app/src/main/java/com/messark/hawker/MainViewModel.kt
  • app/src/test/java/com/messark/hawker/BossWaveLogicTest.kt
  • app/src/test/java/com/messark/hawker/KitchelinBonusTest.kt
  • app/src/test/java/com/messark/hawker/LegendaryNamingTest.kt
  • app/src/test/java/com/messark/hawker/MainViewModelTest.kt
  • app/src/test/java/com/messark/hawker/MilestoneBoostTest.kt
  • app/src/test/java/com/messark/hawker/StallStatsTest.kt
  • app/src/test/java/com/messark/hawker/UndeadEnemyTest.kt
🚧 Files skipped from review as they are similar to previous changes (3)
  • app/src/test/java/com/messark/hawker/LegendaryNamingTest.kt
  • app/src/test/java/com/messark/hawker/KitchelinBonusTest.kt
  • app/src/test/java/com/messark/hawker/MilestoneBoostTest.kt

@candour
candour merged commit 1aee246 into main May 2, 2026
3 checks passed
@candour
candour deleted the port-pr-114-fixes-7969685778257572278 branch May 2, 2026 08:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant