fix(shift): persist name field, guard empty cycle, test corrupt-data path
This commit is contained in:
parent
e4834a52c9
commit
1f1db17384
@ -21,6 +21,7 @@ class ShiftPatternStorage(private val prefs: SharedPreferences) {
|
|||||||
private const val KEY_CYCLE = "shift_cycle"
|
private const val KEY_CYCLE = "shift_cycle"
|
||||||
private const val KEY_OVERRIDES = "shift_overrides"
|
private const val KEY_OVERRIDES = "shift_overrides"
|
||||||
private const val KEY_BREAKS = "shift_breaks"
|
private const val KEY_BREAKS = "shift_breaks"
|
||||||
|
private const val KEY_NAME = "shift_name"
|
||||||
private const val SEP = ","
|
private const val SEP = ","
|
||||||
|
|
||||||
fun fromContext(context: Context): ShiftPatternStorage =
|
fun fromContext(context: Context): ShiftPatternStorage =
|
||||||
@ -40,6 +41,7 @@ class ShiftPatternStorage(private val prefs: SharedPreferences) {
|
|||||||
.putString(KEY_CYCLE, cycleStr)
|
.putString(KEY_CYCLE, cycleStr)
|
||||||
.putString(KEY_OVERRIDES, overridesStr)
|
.putString(KEY_OVERRIDES, overridesStr)
|
||||||
.putString(KEY_BREAKS, breaksStr)
|
.putString(KEY_BREAKS, breaksStr)
|
||||||
|
.putString(KEY_NAME, pattern.name)
|
||||||
.apply()
|
.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,10 +50,14 @@ class ShiftPatternStorage(private val prefs: SharedPreferences) {
|
|||||||
val cycleStr = prefs.getString(KEY_CYCLE, null) ?: return null
|
val cycleStr = prefs.getString(KEY_CYCLE, null) ?: return null
|
||||||
return try {
|
return try {
|
||||||
val anchor = LocalDate.parse(anchorStr)
|
val anchor = LocalDate.parse(anchorStr)
|
||||||
val cycle = cycleStr.split(SEP).map { if (it.trim() == "1") ShiftKind.WORK else ShiftKind.OFF }
|
val cycle = if (cycleStr.isBlank()) {
|
||||||
|
emptyList()
|
||||||
|
} else {
|
||||||
|
cycleStr.split(SEP).map { if (it.trim() == "1") ShiftKind.WORK else ShiftKind.OFF }
|
||||||
|
}
|
||||||
val overrides = parseOverrides(prefs.getString(KEY_OVERRIDES, null))
|
val overrides = parseOverrides(prefs.getString(KEY_OVERRIDES, null))
|
||||||
val breaks = parseBreaks(prefs.getString(KEY_BREAKS, null))
|
val breaks = parseBreaks(prefs.getString(KEY_BREAKS, null))
|
||||||
ShiftPattern(anchor, cycle, overrides, breaks)
|
ShiftPattern(anchor, cycle, overrides, breaks, name = prefs.getString(KEY_NAME, null) ?: "默认")
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,6 +58,44 @@ class ShiftPatternStorageTest {
|
|||||||
storage.save(pattern)
|
storage.save(pattern)
|
||||||
assertEquals(pattern, storage.load())
|
assertEquals(pattern, storage.load())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun load_corruptOverrides_returnsNull() {
|
||||||
|
storage.clear()
|
||||||
|
// 通过底层 prefs 注入损坏的 overrides 值
|
||||||
|
prefs.edit()
|
||||||
|
.putString("shift_anchor", "2026-05-15")
|
||||||
|
.putString("shift_cycle", "1,1,0,0")
|
||||||
|
.putString("shift_overrides", "not-a-date:1")
|
||||||
|
.apply()
|
||||||
|
assertNull(storage.load())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun saveAndLoad_customName_preserved() {
|
||||||
|
storage.clear()
|
||||||
|
val pattern = ShiftPattern(
|
||||||
|
anchorDate = LocalDate(2026, 5, 15),
|
||||||
|
cycle = listOf(ShiftKind.WORK, ShiftKind.OFF),
|
||||||
|
name = "我的方案"
|
||||||
|
)
|
||||||
|
storage.save(pattern)
|
||||||
|
val loaded = storage.load()
|
||||||
|
assertEquals(pattern, loaded)
|
||||||
|
assertEquals("我的方案", loaded?.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun saveAndLoad_emptyCycle_roundTrips() {
|
||||||
|
storage.clear()
|
||||||
|
val pattern = ShiftPattern(
|
||||||
|
anchorDate = LocalDate(2026, 5, 15),
|
||||||
|
cycle = emptyList()
|
||||||
|
)
|
||||||
|
storage.save(pattern)
|
||||||
|
val loaded = storage.load()
|
||||||
|
assertEquals(pattern, loaded)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 复制自 DateCheckerStorageTest(其为 private,无法共享);重命名以避免同包下 private 类同名冲突
|
// 复制自 DateCheckerStorageTest(其为 private,无法共享);重命名以避免同包下 private 类同名冲突
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user