fix(jetbrains): keep applied settings visible

This commit is contained in:
kirillk
2026-07-17 17:20:29 -04:00
parent 8f37445bde
commit 63fefce174
3 changed files with 91 additions and 1 deletions
@@ -11,6 +11,8 @@ internal class SettingsDraftState<D>(
private var base = initial
private var pending: D? = null
private var stale: List<D> = emptyList()
private var applied: D? = null
private var save = false
private var err: String? = null
@@ -29,6 +31,10 @@ internal class SettingsDraftState<D>(
fun accept(next: D) {
val target = pending
if (target == null) {
val done = applied
if (done != null && saved(base, done) && stale.any { saved(next, it) }) return
stale = emptyList()
applied = null
val prev = base
val edit = draft
base = next
@@ -51,12 +57,15 @@ internal class SettingsDraftState<D>(
fun complete(token: SettingsDraftSave<D>, returned: D) {
val edit = draft
val next = if (saved(returned, token.target)) returned else token.target
val fresh = saved(returned, token.target)
val next = if (fresh) returned else token.target
base = next
draft = if (saved(edit, token.target)) next else edit
pending = null
save = false
err = null
stale += token.previous
applied = token.target
}
fun fail(token: SettingsDraftSave<D>, message: String) {
@@ -66,6 +75,8 @@ internal class SettingsDraftState<D>(
pending = null
save = false
err = message
stale = emptyList()
applied = null
}
}
@@ -88,6 +88,66 @@ class SettingsDraftStateTest {
assertFalse(state.modified())
}
@Test
fun `stale external base after fallback completion does not revert applied target`() {
val state = SettingsDraftState("old")
state.update { "new" }
val token = state.start()!!
state.complete(token, "old")
state.accept("old")
assertEquals("new", state.baseline)
assertEquals("new", state.draft)
assertFalse(state.modified())
}
@Test
fun `stale external base after fresh completion does not revert applied target`() {
val state = SettingsDraftState("old")
state.update { "new" }
val token = state.start()!!
state.complete(token, "new")
state.accept("old")
assertEquals("new", state.baseline)
assertEquals("new", state.draft)
assertFalse(state.modified())
}
@Test
fun `fresh external base after ignored stale update is accepted`() {
val state = SettingsDraftState("old")
state.update { "new" }
val token = state.start()!!
state.complete(token, "old")
state.accept("old")
state.accept("other")
assertEquals("other", state.baseline)
assertEquals("other", state.draft)
assertFalse(state.modified())
}
@Test
fun `older stale external base after multiple saves is ignored`() {
val state = SettingsDraftState("old")
state.update { "new" }
val first = state.start()!!
state.complete(first, "new")
state.update { "other" }
val second = state.start()!!
state.complete(second, "other")
state.accept("old")
assertEquals("other", state.baseline)
assertEquals("other", state.draft)
assertFalse(state.modified())
}
@Test
fun `failed save keeps draft dirty and restores previous base`() {
val state = SettingsDraftState("old")
@@ -148,6 +148,25 @@ class ContextSettingsUiTest : BasePlatformTestCase() {
assertEquals(listOf("tmp/**", "**/dist/**"), rpc.configPatches.single().watcher?.ignore)
}
fun `test stale config update result keeps watcher pattern visible`() {
val panel = requireUi()
rpc.configUpdateReturnStale = true
edt {
val patterns = components(panel).filterIsInstance<PatternList>().single()
patterns.input = { "**/dist/**" }
icon(panel, "Add pattern").doClick()
panel.applyDraft()
}
flushUntil { rpc.configPatches.isNotEmpty() && !edt { panel.modified() } }
edt {
val list = patternList(panel)
assertEquals(listOf("**/dist/**"), list.selectedValuesList)
assertEquals(listOf("tmp/**", "**/dist/**"), (0 until list.model.size).map { list.model.getElementAt(it) })
}
}
fun `test removing selected watcher patterns supports multi selection`() {
val panel = requireUi()