feat(state): 迁移 home 与 localBattleUserState 两个内联切片
This commit is contained in:
1 parent
fba31fb63c
commit
cd680708bd
9 files changed
+196
-33
No files matched your search
@@ -143,13 +143,15 @@
|
||||
`names/root_wiring.json` + `TankiOffline/.../App/State/RootState.kt`、`RootWiring.kt`。
|
||||
- 根状态 `z6`(`TOState`)的 **89 个槽位**全部入表;字段顺序取 `toString`,槽位取构造函数 `<名>_1`。
|
||||
- 根 reducer `k6` 的逐切片委派记全:reducer 引用、委派表达式、顶层 `instanceof` 动作名。
|
||||
- 已迁移切片 **3/89**:
|
||||
- 已迁移切片 **5/89**:
|
||||
- `inviteState` → `aD` / `pD.er5`(`InviteReducer.kt`)
|
||||
- `loginByPassword` → `gD` / `MD.cr6`(`LoginReducer.kt`,含 `SetLogin`/`SetPassword` 把 status 打回 `NONE` 的原语义)
|
||||
- `twitchState` → `g9` / `y9.gta`(`TwitchReducer.kt`;`SetAccount` 是 Twitch 账号,不是 UID)
|
||||
- `App/State/RootReducer.kt`:`ReduceRoot(State0, Action)` 只归约上述三片,其余 **86 个字段原样透传**;
|
||||
迁移进度用 `RootReducer.Coverage`(`已迁移 3/89`)与 `RootWiring.Unmigrated` 暴露。
|
||||
- 自检:`TankiOffline/tools/RunStateTest.ps1` **61 项全绿**,含 89 槽位完整性、三片一次归约互不串片、未迁移字段透传。
|
||||
- `home` → `s1` / 根 reducer `(inline@home)` 分支(`HomeReducer.kt`;`ShopDiscountNotification`)
|
||||
- `localBattleUserState` → `lE` / `(inline@localBattleUserState)` 分支(`LocalBattleUserReducer.kt`)
|
||||
- `App/State/RootReducer.kt`:`ReduceRoot(State0, Action)` 只归约上述五片,其余 **84 个字段原样透传**;
|
||||
迁移进度用 `RootReducer.Coverage`(`已迁移 5/89`)与 `RootWiring.Unmigrated` 暴露。
|
||||
- 自检:`TankiOffline/tools/RunStateTest.ps1` **78 项全绿**,含 89 槽位完整性、五片一次归约互不串片、未迁移字段透传。
|
||||
- 委派表里的已知形态:`shop` / `home` / `localBattleUserState` / `partner` 是内联 IIFE,
|
||||
已按字段具名为 `(inline@<field>)` 并从函数体抓到顶层动作名(69 / 1 / 2 / 11 个);
|
||||
`launchParams` 是纯透传(`(pass-through)`,无 reducer)。
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"generatedAt": "2026-10-22T17:18:31.765Z",
|
||||
"generatedAt": "2026-10-22T17:21:56.934Z",
|
||||
"module": "module_10032.js",
|
||||
"RootState": {
|
||||
"Class": "z6",
|
||||
@@ -9,7 +9,9 @@
|
||||
"Migrated": [
|
||||
"inviteState",
|
||||
"loginByPassword",
|
||||
"twitchState"
|
||||
"twitchState",
|
||||
"home",
|
||||
"localBattleUserState"
|
||||
],
|
||||
"AnonymousActions": [
|
||||
{
|
||||
@@ -1122,7 +1124,7 @@
|
||||
"ShowShopDiscountNotification"
|
||||
],
|
||||
"Default": "new s1()",
|
||||
"Migrated": false
|
||||
"Migrated": true
|
||||
},
|
||||
{
|
||||
"Field": "localBattleUserState",
|
||||
@@ -1135,7 +1137,7 @@
|
||||
"SetReArmorTemporaryDisabled"
|
||||
],
|
||||
"Default": "new lE()",
|
||||
"Migrated": false
|
||||
"Migrated": true
|
||||
},
|
||||
{
|
||||
"Field": "soundSettings",
|
||||
|
||||
@@ -393,6 +393,8 @@ const Migrated = {
|
||||
inviteState: { Type: 'InviteStateSlice', Reduce: 'ReduceInvite' },
|
||||
loginByPassword: { Type: 'LoginByPasswordStateSlice', Reduce: 'ReduceLoginByPassword' },
|
||||
twitchState: { Type: 'TwitchStateSlice', Reduce: 'ReduceTwitch' },
|
||||
home: { Type: 'HomeStateSlice', Reduce: 'ReduceHome' },
|
||||
localBattleUserState: { Type: 'LocalBattleUserStateSlice', Reduce: 'ReduceLocalBattleUser' },
|
||||
};
|
||||
|
||||
for (const R of Rows) R.Migrated = Object.prototype.hasOwnProperty.call(Migrated, R.Field);
|
||||
@@ -446,9 +448,9 @@ Lines.push('// 与根 reducer ' + RootReducerFn.Name + '(逐切片归约
|
||||
Lines.push('// 已迁移的切片用强类型;其余保持 Any?(原样透传),迁移一个改一个再重新生成。');
|
||||
Lines.push('package App.State');
|
||||
Lines.push('');
|
||||
Lines.push('import App.State.Reducers.InviteStateSlice');
|
||||
Lines.push('import App.State.Reducers.LoginByPasswordStateSlice');
|
||||
Lines.push('import App.State.Reducers.TwitchStateSlice');
|
||||
for (const F of Object.keys(Migrated).sort()) {
|
||||
Lines.push('import App.State.Reducers.' + Migrated[F].Type);
|
||||
}
|
||||
Lines.push('');
|
||||
Lines.push('/**');
|
||||
Lines.push(' * 原 `' + RootClass + '` / `TOState`:' + Rows.length + ' 个切片字段,顺序与 toString 一致。');
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// HomeReducer.kt —— 首页切片(对应 module_10032 的 s1 状态 + 根 reducer 的 home 内联分支)
|
||||
//
|
||||
// 证据链:
|
||||
// 状态类 s1:`function s1(t) { t = t !== cd && t; this.esm_1 = t; }`
|
||||
// toString:`HomeScreen(shopDiscountNotification=… )`,默认 false
|
||||
// 归约:根 reducer `k6` 的 home 分支(原内联 IIFE,委派表记为 `(inline@home)`)
|
||||
// `(function (t, n) { return t instanceof o1 ? n.f7j(!0) : n; })(t, n.tpw_1)`
|
||||
// `ld(s1).f7j = function (t) { return new s1(t); }` 是 copy,`!0` 即新值 true
|
||||
// 动作 o1:无字段、无 toString(10032 以 `$_$.gl` 导出单例 `Eh`),按 reducer 效果定名
|
||||
// `ShowShopDiscountNotification`;命名证据见 `3DTank/names/root_wiring.json` 的 AnonymousActions
|
||||
// (派发点 module_18334 的 `nt(Qx).qge`,即主菜单商店项上的折扣提示)。
|
||||
package App.State.Reducers
|
||||
|
||||
/**
|
||||
* 原 `o1`:无字段、无 toString 的默认动作;效果是 `HomeScreen.copy(shopDiscountNotification = true)`。
|
||||
*/
|
||||
class ShowShopDiscountNotification
|
||||
|
||||
/**
|
||||
* 原 `s1` / `HomeScreen`:`HomeScreen(shopDiscountNotification)`,默认 false。
|
||||
*/
|
||||
data class HomeStateSlice(
|
||||
val ShopDiscountNotification: Boolean = false,
|
||||
)
|
||||
|
||||
/** 根 reducer 的 home 分支(原内联 IIFE,`(inline@home)`)。 */
|
||||
fun ReduceHome(State0: HomeStateSlice, A: Any): HomeStateSlice = when (A) {
|
||||
is ShowShopDiscountNotification -> State0.copy(ShopDiscountNotification = true)
|
||||
else -> State0
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// LocalBattleUserReducer.kt —— 本地战斗用户切片(对应 module_10032 的 lE 状态 + 根 reducer 的 upw_1 内联分支)
|
||||
//
|
||||
// 证据链:
|
||||
// 状态类 lE:`function lE(t, n) { t = t === cd ? null : t; n = n !== cd && n;
|
||||
// this.uq8_1 = t; this.vq8_1 = n; }`
|
||||
// toString:`LocalBattleUserState(weaponResistanceProperty=…, isReArmorTemporaryDisabled=…)`
|
||||
// 默认值:`null / false`
|
||||
// 归约:根 reducer `k6` 的 localBattleUserState 分支(原内联 IIFE,委派表记为 `(inline@localBattleUserState)`)
|
||||
// `(function (t, n) {
|
||||
// return t instanceof fE ? n.xq8(t.yq8_1)
|
||||
// : t instanceof vE ? n.xq8(cd, t.zq8_1)
|
||||
// : n;
|
||||
// })(t, n.upw_1)`
|
||||
// `ld(lE).xq8` 是 copy(缺省实参取自身字段)
|
||||
// 动作(都在 action_inventory_10032 里):
|
||||
// fE → SetLocalWeaponResistanceProperty(itemProperty: String) 10032 导出 `$_$.ru`
|
||||
// vE → SetReArmorTemporaryDisabled(disabled: Boolean) 10032 导出 `$_$.su`
|
||||
// 派发点例:module_70130 的 `this.z1vd_1.uar(new _a(!t.equals(oa())))`
|
||||
package App.State.Reducers
|
||||
|
||||
import App.State.SetLocalWeaponResistanceProperty
|
||||
import App.State.SetReArmorTemporaryDisabled
|
||||
|
||||
/**
|
||||
* 原 `lE`:`LocalBattleUserState(weaponResistanceProperty, isReArmorTemporaryDisabled)`。
|
||||
* 默认值取自原构造函数:`null / false`。
|
||||
*/
|
||||
data class LocalBattleUserStateSlice(
|
||||
val WeaponResistanceProperty: String? = null,
|
||||
val IsReArmorTemporaryDisabled: Boolean = false,
|
||||
)
|
||||
|
||||
/** 根 reducer 的 localBattleUserState 分支(原内联 IIFE,`(inline@localBattleUserState)`)。 */
|
||||
fun ReduceLocalBattleUser(State0: LocalBattleUserStateSlice, A: Any): LocalBattleUserStateSlice = when (A) {
|
||||
is SetLocalWeaponResistanceProperty -> State0.copy(WeaponResistanceProperty = A.itemProperty)
|
||||
is SetReArmorTemporaryDisabled -> State0.copy(IsReArmorTemporaryDisabled = A.disabled)
|
||||
else -> State0
|
||||
}
|
||||
@@ -6,13 +6,17 @@
|
||||
// inviteState → ReduceInvite(aD / pD.er5)
|
||||
// loginByPassword → ReduceLoginByPassword(gD / MD.cr6)
|
||||
// twitchState → ReduceTwitch(g9 / y9.gta)
|
||||
// home → ReduceHome(s1 / 根 reducer 的 `(inline@home)` 分支)
|
||||
// localBattleUserState → ReduceLocalBattleUser(lE / `(inline@localBattleUserState)` 分支)
|
||||
//
|
||||
// 其余 86 个字段按原样透传(defaultValue 取原构造)。每个切片 reducer 对无关动作都返回原状态,
|
||||
// 其余 84 个字段按原样透传(defaultValue 取原构造)。每个切片 reducer 对无关动作都返回原状态,
|
||||
// 所以一次 copy 里串起全部已迁移 reducer,与按动作路由再归约的结果一致。
|
||||
// 迁移进度与每个字段的证据见生成物 RootWiring.kt(不要手改)。
|
||||
package App.State
|
||||
|
||||
import App.State.Reducers.ReduceHome
|
||||
import App.State.Reducers.ReduceInvite
|
||||
import App.State.Reducers.ReduceLocalBattleUser
|
||||
import App.State.Reducers.ReduceLoginByPassword
|
||||
import App.State.Reducers.ReduceTwitch
|
||||
|
||||
@@ -32,6 +36,8 @@ object RootReducer {
|
||||
InviteState = ReduceInvite(State0.InviteState, Action),
|
||||
LoginByPassword = ReduceLoginByPassword(State0.LoginByPassword, Action),
|
||||
TwitchState = ReduceTwitch(State0.TwitchState, Action),
|
||||
Home = ReduceHome(State0.Home, Action),
|
||||
LocalBattleUserState = ReduceLocalBattleUser(State0.LocalBattleUserState, Action),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
// 已迁移的切片用强类型;其余保持 Any?(原样透传),迁移一个改一个再重新生成。
|
||||
package App.State
|
||||
|
||||
import App.State.Reducers.HomeStateSlice
|
||||
import App.State.Reducers.InviteStateSlice
|
||||
import App.State.Reducers.LocalBattleUserStateSlice
|
||||
import App.State.Reducers.LoginByPasswordStateSlice
|
||||
import App.State.Reducers.TwitchStateSlice
|
||||
|
||||
@@ -107,10 +109,10 @@ data class RootState(
|
||||
val BattleChat: Any? = null,
|
||||
/** 原 droppableGold(Vet / Wp.kth)。未迁移:原样透传。 */
|
||||
val DroppableGold: Any? = null,
|
||||
/** 原 home(s1 / (inline@home))。未迁移:原样透传。 */
|
||||
val Home: Any? = null,
|
||||
/** 原 localBattleUserState(lE / (inline@localBattleUserState))。未迁移:原样透传。 */
|
||||
val LocalBattleUserState: Any? = null,
|
||||
/** 原 home(s1 / (inline@home))。已迁移。 */
|
||||
val Home: HomeStateSlice = HomeStateSlice(),
|
||||
/** 原 localBattleUserState(lE / (inline@localBattleUserState))。已迁移。 */
|
||||
val LocalBattleUserState: LocalBattleUserStateSlice = LocalBattleUserStateSlice(),
|
||||
/** 原 soundSettings(Det / Wet().jth)。未迁移:原样透传。 */
|
||||
val SoundSettings: Any? = null,
|
||||
/** 原 gameSettings(c2 / g2().zss)。未迁移:原样透传。 */
|
||||
|
||||
@@ -106,7 +106,7 @@ object RootWiring {
|
||||
)
|
||||
|
||||
/** 已迁移(由 RootReducer 真正归约)的字段。 */
|
||||
val Migrated: Set<String> = setOf("inviteState", "loginByPassword", "twitchState")
|
||||
val Migrated: Set<String> = setOf("inviteState", "loginByPassword", "twitchState", "home", "localBattleUserState")
|
||||
|
||||
/** 未迁移字段:归约时原样透传,作为后续迁移清单。 */
|
||||
val Unmigrated: List<SliceWiring> get() = All.filter { it.Field !in Migrated }
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
// ⑥ 动作目录:816 个类与 138 个真实派发名对齐
|
||||
// ⑦ 回放:真实 toString 样例的类/字段/类型校验
|
||||
// ⑧ 全目录动作类都能按 KClass 路由
|
||||
// ⑨~⑫ 切片 reducer:InviteState / LoginByPasswordState / TwitchState;⑫ 根 reducer 的 89 槽位委派
|
||||
// ⑨~⑭ 切片 reducer:InviteState / LoginByPasswordState / TwitchState / HomeScreen / LocalBattleUserState;⑭ 根 reducer 的 89 槽位委派
|
||||
//
|
||||
// 用法:$env:TANKIOFFLINE_STATE_TEST='1'; node …(见 TankiOffline/tools/RunStateTest.ps1)
|
||||
package App
|
||||
@@ -22,15 +22,20 @@ import App.State.ActionCatalog
|
||||
import App.State.ActionSamples
|
||||
import App.State.ApplyInvite
|
||||
import App.State.Reducers.ByPasswordStatus
|
||||
import App.State.Reducers.HomeStateSlice
|
||||
import App.State.Reducers.InviteStateSlice
|
||||
import App.State.Reducers.InviteStatus
|
||||
import App.State.Reducers.LocalBattleUserStateSlice
|
||||
import App.State.Reducers.LoginByPasswordStateSlice
|
||||
import App.State.Reducers.LoginOnly
|
||||
import App.State.Reducers.ReduceHome
|
||||
import App.State.Reducers.ReduceInvite
|
||||
import App.State.Reducers.ReduceLocalBattleUser
|
||||
import App.State.Reducers.ReduceLoginByPassword
|
||||
import App.State.Reducers.ReduceTwitch
|
||||
import App.State.Reducers.ResetLoginByPassword
|
||||
import App.State.Reducers.ResetLoginByPasswordStatus
|
||||
import App.State.Reducers.ShowShopDiscountNotification
|
||||
import App.State.Reducers.TwitchStateSlice
|
||||
import App.State.ReduceRoot
|
||||
import App.State.RootReducer
|
||||
@@ -42,8 +47,10 @@ import App.State.SetAccount
|
||||
import App.State.SetDaysForNextLinking
|
||||
import App.State.SetInviteNeed
|
||||
import App.State.SetInviteStatus
|
||||
import App.State.SetLocalWeaponResistanceProperty
|
||||
import App.State.SetLogin
|
||||
import App.State.SetPassword
|
||||
import App.State.SetReArmorTemporaryDisabled
|
||||
import App.State.SetRememberMe
|
||||
import App.State.SetStatus
|
||||
import App.State.SetTwitchEnabled
|
||||
@@ -377,7 +384,50 @@ object StateCheck {
|
||||
Check("切片 Twitch:接 Store 派发后状态已归约", Store.State.DaysForNextLinking == 2)
|
||||
}
|
||||
|
||||
// ⑫ 根 reducer:89 个槽位的委派表 + 三个已迁移切片一次归约
|
||||
// ⑫ 切片 reducer:HomeScreen(原 module_10032 的 s1 + 根 reducer `(inline@home)` 分支)
|
||||
run {
|
||||
val S0 = HomeStateSlice()
|
||||
Check("切片 Home:默认值与 HomeScreen 一致", !S0.ShopDiscountNotification)
|
||||
|
||||
// 动作 o1(无 toString,定名 ShowShopDiscountNotification)→ copy(shopDiscountNotification = true)
|
||||
val S1 = ReduceHome(S0, ShowShopDiscountNotification())
|
||||
Check("切片 Home:ShowShopDiscountNotification 把折扣提示置 true", S1.ShopDiscountNotification)
|
||||
|
||||
Check("切片 Home:无关动作不改状态", ReduceHome(S1, AddFrags(1)) == S1)
|
||||
|
||||
val Store = ReduxStore(S0, { S, A -> ReduceHome(S, A) })
|
||||
Store.Dispatch(ShowShopDiscountNotification())
|
||||
Check("切片 Home:接 Store 派发后状态已归约", Store.State.ShopDiscountNotification)
|
||||
}
|
||||
|
||||
// ⑬ 切片 reducer:LocalBattleUserState(原 module_10032 的 lE + 根 reducer `(inline@localBattleUserState)`)
|
||||
run {
|
||||
val S0 = LocalBattleUserStateSlice()
|
||||
Check(
|
||||
"切片 LocalBattleUser:默认值与原构造一致",
|
||||
S0.WeaponResistanceProperty == null && !S0.IsReArmorTemporaryDisabled
|
||||
)
|
||||
|
||||
val S1 = ReduceLocalBattleUser(S0, SetLocalWeaponResistanceProperty("FREEZE_RESISTANCE"))
|
||||
Check(
|
||||
"切片 LocalBattleUser:SetLocalWeaponResistanceProperty 只写武器抗性属性",
|
||||
S1.WeaponResistanceProperty == "FREEZE_RESISTANCE" && !S1.IsReArmorTemporaryDisabled
|
||||
)
|
||||
|
||||
val S2 = ReduceLocalBattleUser(S1, SetReArmorTemporaryDisabled(true))
|
||||
Check(
|
||||
"切片 LocalBattleUser:SetReArmorTemporaryDisabled 只改开关",
|
||||
S2.IsReArmorTemporaryDisabled && S2.WeaponResistanceProperty == "FREEZE_RESISTANCE"
|
||||
)
|
||||
Check("切片 LocalBattleUser:SetReArmorTemporaryDisabled(false) 关掉", !ReduceLocalBattleUser(S2, SetReArmorTemporaryDisabled(false)).IsReArmorTemporaryDisabled)
|
||||
Check("切片 LocalBattleUser:无关动作不改状态", ReduceLocalBattleUser(S2, AddFrags(1)) == S2)
|
||||
|
||||
val Store = ReduxStore(S0, { S, A -> ReduceLocalBattleUser(S, A) })
|
||||
Store.Dispatch(SetReArmorTemporaryDisabled(true))
|
||||
Check("切片 LocalBattleUser:接 Store 派发后状态已归约", Store.State.IsReArmorTemporaryDisabled)
|
||||
}
|
||||
|
||||
// ⑭ 根 reducer:89 个槽位的委派表 + 五个已迁移切片一次归约
|
||||
run {
|
||||
Check("根:根状态 89 个切片槽位", RootWiring.All.size == 89)
|
||||
Check(
|
||||
@@ -428,20 +478,34 @@ object StateCheck {
|
||||
"根:twitchState 委派到 g9 / uf.gta",
|
||||
TwitchW != null && TwitchW.SliceClass == "g9" && TwitchW.Reducer == "uf.gta"
|
||||
)
|
||||
// 后两片是内联 IIFE,委派名是 `(inline@<field>)`
|
||||
val HomeW = RootWiring.ByField("home")
|
||||
val LocalBattleW = RootWiring.ByField("localBattleUserState")
|
||||
Check(
|
||||
"根:迁移表 = 三个已迁移字段,其余 86 个待迁",
|
||||
RootReducer.Migrated == setOf("inviteState", "loginByPassword", "twitchState") &&
|
||||
RootWiring.Unmigrated.size == 86
|
||||
"根:home 委派到 s1 / (inline@home)",
|
||||
HomeW != null && HomeW.SliceClass == "s1" && HomeW.Reducer == "(inline@home)"
|
||||
)
|
||||
Check(
|
||||
"根:localBattleUserState 委派到 lE / (inline@localBattleUserState)",
|
||||
LocalBattleW != null && LocalBattleW.SliceClass == "lE" &&
|
||||
LocalBattleW.Reducer == "(inline@localBattleUserState)"
|
||||
)
|
||||
Check(
|
||||
"根:迁移表 = 五个已迁移字段,其余 84 个待迁",
|
||||
RootReducer.Migrated ==
|
||||
setOf("inviteState", "loginByPassword", "twitchState", "home", "localBattleUserState") &&
|
||||
RootWiring.Unmigrated.size == 84
|
||||
)
|
||||
|
||||
// 一次 ReduceRoot 里三个切片各归约自己的动作,互不串片
|
||||
// 一次 ReduceRoot 里五个切片各归约自己的动作,互不串片
|
||||
val S0 = RootState(User = "user-1", Screen = "Preloader")
|
||||
val S1 = ReduceRoot(S0, ApplyInvite("uid-1"))
|
||||
Check(
|
||||
"根:ApplyInvite 只动 inviteState",
|
||||
S1.InviteState.Invite == "uid-1" &&
|
||||
S1.LoginByPassword == S0.LoginByPassword &&
|
||||
S1.TwitchState == S0.TwitchState
|
||||
S1.TwitchState == S0.TwitchState &&
|
||||
S1.Home == S0.Home
|
||||
)
|
||||
|
||||
val S2 = ReduceRoot(S1, SetLogin("pilot"))
|
||||
@@ -459,27 +523,44 @@ object StateCheck {
|
||||
S3.InviteState == S2.InviteState &&
|
||||
S3.LoginByPassword == S2.LoginByPassword
|
||||
)
|
||||
|
||||
val S4 = ReduceRoot(S3, ShowShopDiscountNotification())
|
||||
Check(
|
||||
"根:三次归约后三个切片各自保留结果",
|
||||
S3.InviteState.Invite == "uid-1" &&
|
||||
S3.LoginByPassword.Login == "pilot" &&
|
||||
S3.TwitchState.TwitchAccount == "tank_tv"
|
||||
"根:ShowShopDiscountNotification 只动 home",
|
||||
S4.Home.ShopDiscountNotification && S4.TwitchState == S3.TwitchState
|
||||
)
|
||||
|
||||
val S5 = ReduceRoot(S4, SetReArmorTemporaryDisabled(true))
|
||||
Check(
|
||||
"根:SetReArmorTemporaryDisabled 只动 localBattleUserState",
|
||||
S5.LocalBattleUserState.IsReArmorTemporaryDisabled && S5.Home == S4.Home
|
||||
)
|
||||
Check(
|
||||
"根:五次归约后五个切片各自保留结果",
|
||||
S5.InviteState.Invite == "uid-1" &&
|
||||
S5.LoginByPassword.Login == "pilot" &&
|
||||
S5.TwitchState.TwitchAccount == "tank_tv" &&
|
||||
S5.Home.ShopDiscountNotification &&
|
||||
S5.LocalBattleUserState.IsReArmorTemporaryDisabled
|
||||
)
|
||||
|
||||
// 未迁移字段原样透传;无关动作不改变任何字段
|
||||
Check(
|
||||
"根:未迁移字段原样透传",
|
||||
S3.User == "user-1" && S3.Screen == "Preloader"
|
||||
S5.User == "user-1" && S5.Screen == "Preloader"
|
||||
)
|
||||
Check("根:无关动作返回等值状态", ReduceRoot(S3, AddFrags(1)) == S3)
|
||||
Check("根:Coverage 文本", RootReducer.Coverage == "已迁移 3/89")
|
||||
Check("根:无关动作返回等值状态", ReduceRoot(S5, AddFrags(1)) == S5)
|
||||
Check("根:Coverage 文本", RootReducer.Coverage == "已迁移 5/89")
|
||||
|
||||
val Store = ReduxStore(RootState(), { S, A -> ReduceRoot(S, A) })
|
||||
Store.Dispatch(SetStatus("LOGGING_IN"))
|
||||
Store.Dispatch(SetTwitchEnabled(true))
|
||||
Store.Dispatch(ShowShopDiscountNotification())
|
||||
Check(
|
||||
"根:接 Store 派发后两片同时归约",
|
||||
Store.State.LoginByPassword.Status == ByPasswordStatus.LOGGING_IN && Store.State.TwitchState.IsTwitchEnabled
|
||||
"根:接 Store 派发后三片同时归约",
|
||||
Store.State.LoginByPassword.Status == ByPasswordStatus.LOGGING_IN &&
|
||||
Store.State.TwitchState.IsTwitchEnabled &&
|
||||
Store.State.Home.ShopDiscountNotification
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user