Support interactive add/stage input flow

This commit is contained in:
Joe Tretter
2026-05-13 19:12:06 -05:00
parent 482483deed
commit 3f6a764603
7 changed files with 150 additions and 5 deletions

View File

@@ -327,11 +327,61 @@ class GitSandboxEngineTest {
val (updatedRepo, output) = GitSandboxEngine.execute(repo, "git add -i")
assertFalse(updatedRepo.files.single { it.name == "README" }.staged)
assertTrue(updatedRepo.interactiveAddSession != null)
assertTrue(output.any { it.contains("What now>") })
assertFalse(output.any { it.contains("What now> update") })
assertFalse(output.any { it.contains("What now> quit") })
}
@Test
fun interactiveAddAcceptsUpdateSelectionFromNextInput() {
val repo = RepoState(initialized = true, files = listOf(GitFile("README")))
val (menuRepo, _) = GitSandboxEngine.execute(repo, "git stage -i")
val (updateRepo, updateOutput) = GitSandboxEngine.execute(menuRepo, "2")
val (selectedRepo, selectionOutput) = GitSandboxEngine.execute(updateRepo, "1")
val (quitRepo, quitOutput) = GitSandboxEngine.execute(selectedRepo, "7")
assertTrue(updateRepo.interactiveAddSession?.awaitingUpdateSelection == true)
assertTrue(updateOutput.any { it.contains("Update>>") })
assertTrue(selectedRepo.files.single { it.name == "README" }.staged)
assertTrue(selectedRepo.interactiveAddSession?.awaitingUpdateSelection == false)
assertTrue(selectionOutput.any { it.contains("updated 1 path(s)") })
assertTrue(quitRepo.interactiveAddSession == null)
assertTrue(quitOutput.any { it.contains("Bye.") })
}
@Test
fun nativeInteractiveAddSelectionUpdatesGitIndex() {
val git = testGitBinary()
assumeTrue(git.exists() && git.canExecute())
val root = Files.createTempDirectory("githug-interactive-add").toFile()
try {
val runtime = GitRepositoryRuntime(root, git)
val level = level(
id = "interactive-add-test",
title = "Interactive Add Test",
description = "",
hints = emptyList(),
commandSuggestions = emptyList(),
setup = { RepoState(initialized = true, files = listOf(GitFile("README")), branches = mapOf("master" to 0)) },
validator = { _, _ -> false },
)
val repo = runtime.prepareLevel(level)
val (menuRepo, _) = runtime.execute(level, repo, "git stage -i")
val (updateRepo, _) = runtime.execute(level, menuRepo, "2")
val (selectedRepo, _) = runtime.execute(level, updateRepo, "1")
val (quitRepo, _) = runtime.execute(level, selectedRepo, "7")
val (_, statusOutput) = runtime.execute(level, quitRepo, "git status")
assertTrue(selectedRepo.files.single { it.name == "README" }.staged)
assertTrue(quitRepo.interactiveAddSession == null)
assertTrue(statusOutput.any { it.contains("new file:") && it.contains("README") })
} finally {
root.deleteRecursively()
}
}
private fun testGitBinary(): File {
System.getenv("GITHUG_TEST_GIT_BINARY")
?.takeIf { it.isNotBlank() }