Switched to Chatgpt 5.5 and codex.

This commit is contained in:
Joe Tretter
2026-05-02 20:29:31 -05:00
parent 015135da5a
commit 8bcfa2bee4
10 changed files with 485 additions and 111 deletions

View File

@@ -0,0 +1,188 @@
package solutions.tretter.githugandroid
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import java.io.File
class LevelSolutionsTest {
@Test
fun everyLevelHasAKnownSolution() {
assertEquals(
allGithugLevels().map { it.id }.toSet(),
SOLUTIONS.keys,
)
}
@Test
fun levelIdsAreUnique() {
val ids = allGithugLevels().map { it.id }
assertEquals(ids, ids.distinct())
}
@Test
fun knownSolutionsCompleteEveryLevel() {
val evidence = StringBuilder()
evidence.appendLine("GitHug Android level solution evidence")
evidence.appendLine("Engine: GitSandboxEngine")
evidence.appendLine("Levels: ${allGithugLevels().size}")
evidence.appendLine()
val failures = allGithugLevels().mapNotNull { level ->
val commands = SOLUTIONS.getValue(level.id)
var repo = level.setup()
var solved = false
evidence.appendLine("================================================================================")
evidence.appendLine("Level: ${level.id}")
evidence.appendLine("Title: ${level.title}")
evidence.appendLine("Initial repo:")
evidence.append(repo.describeForEvidence().prependIndent(" "))
evidence.appendLine("Solution commands:")
commands.forEachIndexed { index, command ->
evidence.appendLine(" ${index + 1}. $command")
}
evidence.appendLine()
commands.forEachIndexed { index, command ->
val (nextRepo, output) = GitSandboxEngine.execute(repo, command)
repo = nextRepo
solved = level.validator(repo, command)
evidence.appendLine("Command ${index + 1}: $command")
evidence.appendLine("Output:")
if (output.isEmpty()) {
evidence.appendLine(" <no output>")
} else {
output.forEach { line -> evidence.appendLine(" $line") }
}
evidence.appendLine("Repo after command:")
evidence.append(repo.describeForEvidence().prependIndent(" "))
evidence.appendLine("Validator passed after command: $solved")
evidence.appendLine()
}
evidence.appendLine("Final result: ${if (solved) "PASS" else "FAIL"}")
evidence.appendLine()
if (solved) null else "${level.id}: ${commands.joinToString(" && ")}"
}
writeEvidenceLog(evidence.toString())
assertTrue(
"Expected every known solution to complete its level. Failures:\n${failures.joinToString("\n")}",
failures.isEmpty(),
)
}
private companion object {
fun writeEvidenceLog(content: String) {
val repoRoot = File(System.getProperty("user.dir") ?: ".")
val appDir = if (File(repoRoot, "app/build.gradle.kts").exists()) {
File(repoRoot, "app")
} else {
repoRoot
}
val reportDir = File(appDir, "build/reports/level-solutions")
reportDir.mkdirs()
File(reportDir, "level-solutions.log").writeText(content)
}
fun RepoState.describeForEvidence(): String = buildString {
appendLine("initialized=$initialized")
appendLine("headBranch=$headBranch")
appendLine("currentDir=$currentDir")
appendLine("branches=${branches.toSortedMap()}")
appendLine("tags=${tags.sorted()}")
appendLine("remotes=${remotes.toSortedMap()}")
appendLine("config=${config.toSortedMap()}")
appendLine("files=")
if (files.isEmpty()) {
appendLine(" <none>")
} else {
files.sortedBy { it.name }.forEach { file ->
appendLine(" ${file.name} staged=${file.staged} tracked=${file.tracked} content=${file.content.toEvidenceValue()}")
}
}
appendLine("commits=")
if (commits.isEmpty()) {
appendLine(" <none>")
} else {
commits.forEach { commit ->
appendLine(" ${commit.id} ${commit.message}")
}
}
}
fun String.toEvidenceValue(): String {
if (isEmpty()) return "\"\""
return lineSequence().joinToString("\\n", prefix = "\"", postfix = "\"")
}
val SOLUTIONS = mapOf(
"init" to listOf("git init"),
"config" to listOf("git config user.name GitHug", "git config user.email githug@example.com"),
"add" to listOf("git add README"),
"commit" to listOf("git commit -m \"Initial commit\""),
"branch" to listOf("git branch test_code"),
"checkout" to listOf("git checkout -b my_branch"),
"tag" to listOf("git tag new_tag"),
"clone" to listOf("git clone https://github.com/Gazler/cloneme"),
"clone_to_folder" to listOf("git clone https://github.com/Gazler/cloneme my_cloned_repo"),
"ignore" to listOf("echo *.swp >> .gitignore"),
"include" to listOf("echo *.a >> .gitignore", "echo !lib.a >> .gitignore"),
"status" to listOf("database.yml"),
"number_of_files_committed" to listOf("2"),
"rm" to listOf("git rm deleteme.rb"),
"rm_cached" to listOf("git rm --cached deleteme.rb"),
"stash" to listOf("git stash"),
"rename" to listOf("git mv oldfile.txt newfile.txt"),
"restructure" to listOf(
"mkdir src",
"git mv about.html src/about.html",
"git mv contact.html src/contact.html",
"git mv index.html src/index.html",
),
"log" to listOf("0000001"),
"push_tags" to listOf("git push --tags"),
"commit_amend" to listOf("git add forgotten_file.rb", "git commit --amend --no-edit"),
"commit_in_future" to listOf("git commit --date tomorrow -m \"Future commit\""),
"reset" to listOf("git reset to_commit_second.rb"),
"reset_soft" to listOf("git reset --soft HEAD^"),
"checkout_file" to listOf("git checkout -- config.rb"),
"remote" to listOf("my_remote_repo"),
"remote_url" to listOf("https://github.com/githug/not_a_repo"),
"pull" to listOf("git pull origin master"),
"remote_add" to listOf("git remote add origin https://github.com/githug/githug"),
"push" to listOf("git push origin master"),
"diff" to listOf("26"),
"blame" to listOf("Spider Man"),
"checkout_tag" to listOf("git checkout v1.2"),
"checkout_tag_over_branch" to listOf("git checkout tags/v1.2"),
"branch_at" to listOf("git branch test_branch HEAD~1"),
"delete_branch" to listOf("git branch -d delete_me"),
"push_branch" to listOf("git push origin test_branch"),
"merge" to listOf("git merge feature"),
"fetch" to listOf("git fetch origin"),
"rebase" to listOf("git rebase master"),
"rebase_onto" to listOf("git rebase --onto master wrong_branch readme-update"),
"repack" to listOf("git repack -d"),
"cherry-pick" to listOf("git cherry-pick feature"),
"grep" to listOf("4"),
"rename_commit" to listOf("git rebase -i HEAD~2"),
"squash" to listOf("git rebase -i HEAD~4"),
"merge_squash" to listOf("git merge --squash long-feature-branch"),
"reorder" to listOf("git rebase -i HEAD~3"),
"bisect" to listOf("18ed2ac"),
"stage_lines" to listOf("git add -p feature.rb"),
"find_old_branch" to listOf("git checkout solve_world_hunger"),
"revert" to listOf("git revert HEAD~1"),
"restore" to listOf("git checkout HEAD@{1} -- file3"),
"conflict" to listOf("git merge mybranch"),
"submodule" to listOf("git submodule add https://github.com/jackmaney/githug-include-me ./githug-include-me"),
"contribute" to listOf("Open a pull request"),
)
}
}