From b7afe07894c0db64f75cf32ee4a8607702cc0511 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 23 Oct 2026 02:38:36 +0800 Subject: [PATCH] =?UTF-8?q?test(state):=20=E7=94=A8=E7=9C=9F=E5=AE=9E?= =?UTF-8?q?=E6=B4=BE=E5=8F=91=E6=A0=B7=E4=BE=8B=E5=9B=9E=E6=94=BE=E5=95=86?= =?UTF-8?q?=E5=BA=97=E5=88=87=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 3DTank/docs/KtRebuild_Plan.md | 3 +- .../app/src/jsMain/kotlin/App/StateCheck.kt | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/3DTank/docs/KtRebuild_Plan.md b/3DTank/docs/KtRebuild_Plan.md index df93775..7ed9f1a 100644 --- a/3DTank/docs/KtRebuild_Plan.md +++ b/3DTank/docs/KtRebuild_Plan.md @@ -155,7 +155,8 @@ (`ShopLoaded`/`ResetShop`/…/`AddCategoriesWithBonus`/…),原名保留在 `ShopReducer.kt` 注释里。 - `App/State/RootReducer.kt`:`ReduceRoot(State0, Action)` 只归约上述六片,其余 **83 个字段原样透传**; 迁移进度用 `RootReducer.Coverage`(`已迁移 6/89`)与 `RootWiring.Unmigrated` 暴露。 - - 自检:`TankiOffline/tools/RunStateTest.ps1` **113 项全绿**,含 89 槽位完整性、六片一次归约互不串片、未迁移字段透传。 + - 自检:`TankiOffline/tools/RunStateTest.ps1` **120 项全绿**,含 89 槽位完整性、六片一次归约互不串片、未迁移字段透传, + 以及用 `action_trace_merged.json` 真实派发的两条商店动作(`SetCoinPaymentProviderUrl` / `ToggleShopActivity`)回放。 - 委派表里的已知形态:`shop` / `home` / `localBattleUserState` / `partner` 是内联 IIFE, 已按字段具名为 `(inline@)` 并从函数体抓到顶层动作名(69 / 1 / 2 / 11 个); `launchParams` 是纯透传(`(pass-through)`,无 reducer)。 diff --git a/TankiOffline/app/src/jsMain/kotlin/App/StateCheck.kt b/TankiOffline/app/src/jsMain/kotlin/App/StateCheck.kt index 0e93b1c..f3d9971 100644 --- a/TankiOffline/app/src/jsMain/kotlin/App/StateCheck.kt +++ b/TankiOffline/app/src/jsMain/kotlin/App/StateCheck.kt @@ -889,6 +889,41 @@ object StateCheck { R3.Shop.ShopItems == R2.Shop.ShopItems && R3.LoginByPassword == R0.LoginByPassword ) Check("根:shop 迁移后无关动作仍返回等值状态", ReduceRoot(R3, AddFrags(1)) == R3) + + // ⑯ shop 真实派发回放:用 action_trace_merged.json 里实际出现过的两条商店动作 + val UrlRaw = ActionSamples.Raw["SetCoinPaymentProviderUrl"] + val ToggleRaw = ActionSamples.Raw["ToggleShopActivity"] + Check("shop 回放:两条真实动作都在样例表里", UrlRaw != null && ToggleRaw != null) + val Url = UrlRaw!!.substringAfter("url=").substringBeforeLast(")") + val Enabled = ToggleRaw!!.substringAfter("enabled=").substringBeforeLast(")") == "true" + Check( + "shop 回放:样例值与运行时一致", + Url.startsWith("https://open-api.3dtank.com/mgr/tank-pay/") && Enabled + ) + + val P0 = RootState() + val P1 = ReduceRoot(P0, SetCoinPaymentProviderUrl(Url)) + Check( + "shop 回放:真实 SetCoinPaymentProviderUrl 写入完整 URL", + P1.Shop.CoinPaymentProviderUrl == Url + ) + val P2 = ReduceRoot(P1.copy(Shop = P1.Shop.copy(Enabled = false)), ToggleShopActivity(Enabled)) + Check( + "shop 回放:真实 ToggleShopActivity(true) 把 enabled 置 true", + P2.Shop.Enabled && P2.Shop.CoinPaymentProviderUrl == Url + ) + Check( + "shop 回放:只动 shop,其他切片不变", + P2.LoginByPassword == P0.LoginByPassword && P2.Home == P0.Home && + P2.TwitchState == P0.TwitchState && P2.User == P0.User + ) + Check( + "shop 回放:两条动作都在动作目录里", + listOf("SetCoinPaymentProviderUrl", "ToggleShopActivity").all { ActionCatalog.ByName[it] != null } + ) + // 69 个动作里只有 x4 是标记接口(没有独立效果),其余都已有名字 + val ShopUnknown = RootWiring.ByField("shop")!!.Actions.filter { it.startsWith("?") } + Check("shop 回放:唯一未具名的是标记 x4", ShopUnknown == listOf("?x4")) } val Failed = Results.filter { !it.second }