From 7bfb761068b0bdc04a85efb04c895cea94c235cd Mon Sep 17 00:00:00 2001 From: Joe Tretter Date: Thu, 7 May 2026 17:00:04 -0500 Subject: [PATCH] Restore Diff level working-tree change - Add a dedicated native Diff fixture that commits baseline app.rb content and leaves an unstaged line-26 change from data.json to server.json. - Update the Diff level setup metadata so app.rb is no longer represented as an empty file. - Add a native runtime regression for `git diff` showing the expected line-26 hunk. --- app/build.gradle.kts | 4 +- .../githugandroid/NativeLevelFixtures.kt | 45 +++++++++++++++++++ .../tretter/githugandroid/levels/DiffLevel.kt | 9 +++- .../githugandroid/GitSandboxEngineTest.kt | 23 ++++++++++ 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c8e62d8..cde6281 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -19,8 +19,8 @@ android { applicationId = "solutions.tretter.githugandroid" minSdk = 26 targetSdk = 35 - versionCode = 126 - versionName = "0.1.125" + versionCode = 127 + versionName = "0.1.126" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true diff --git a/app/src/main/java/solutions/tretter/githugandroid/NativeLevelFixtures.kt b/app/src/main/java/solutions/tretter/githugandroid/NativeLevelFixtures.kt index 1e524df..091a7d8 100644 --- a/app/src/main/java/solutions/tretter/githugandroid/NativeLevelFixtures.kt +++ b/app/src/main/java/solutions/tretter/githugandroid/NativeLevelFixtures.kt @@ -12,6 +12,7 @@ internal fun materializeNativeLevelFixture( "branch_at" -> fixture.branchAt() "checkout_tag" -> fixture.checkoutTag() "checkout_tag_over_branch" -> fixture.checkoutTagOverBranch() + "diff" -> fixture.diff() "fetch" -> fixture.fetch() "pull" -> fixture.pull() "push_branch" -> fixture.pushBranch() @@ -176,6 +177,14 @@ private class NativeLevelFixture( return true } + fun diff(): Boolean { + resetFiles() + write("app.rb", diffLevelBaselineAppRb()) + addCommit("Add app routes", "app.rb") + write("app.rb", diffLevelModifiedAppRb()) + return true + } + fun pull(): Boolean { resetFiles() write("local_file") @@ -387,3 +396,39 @@ private class NativeLevelFixture( return true } } + +internal fun diffLevelBaselineAppRb(): String = buildString { + appendLine("require 'sinatra'") + appendLine("require 'json'") + appendLine() + appendLine("helpers do") + appendLine(" def get_response(source)") + appendLine(" JSON.parse(File.read(source))['message']") + appendLine(" end") + appendLine("end") + appendLine() + appendLine("get '/' do") + appendLine(" @message = 'hello'") + appendLine(" erb :index") + appendLine("end") + appendLine() + appendLine("get '/page' do") + appendLine(" @message = 'page'") + appendLine(" erb :page") + appendLine("end") + appendLine() + appendLine("get '/yet_another' do") + appendLine(" @message = 'another'") + appendLine(" erb :success") + appendLine("end") + appendLine() + appendLine("get '/another_page' do") + appendLine(" @message = get_response('data.json')") + appendLine(" erb :another") + appendLine("end") + appendLine() + appendLine("# end of application") +} + +internal fun diffLevelModifiedAppRb(): String = + diffLevelBaselineAppRb().replace("get_response('data.json')", "get_response('server.json')") diff --git a/app/src/main/java/solutions/tretter/githugandroid/levels/DiffLevel.kt b/app/src/main/java/solutions/tretter/githugandroid/levels/DiffLevel.kt index d4b4ff7..ecc8157 100644 --- a/app/src/main/java/solutions/tretter/githugandroid/levels/DiffLevel.kt +++ b/app/src/main/java/solutions/tretter/githugandroid/levels/DiffLevel.kt @@ -13,7 +13,14 @@ internal fun diffLevel(): Level = level( description = "Since your last commit, file `app.rb` was modified. Find out which line has changed.", hints = listOf("You are looking for the difference since your last commit."), commandSuggestions = listOf("git diff"), - setup = { RepoState(initialized = true, files = listOf(GitFile("app.rb", tracked = true)), branches = mapOf("master" to 1)) }, + setup = { + RepoState( + initialized = true, + files = listOf(GitFile("app.rb", diffLevelModifiedAppRb(), tracked = true)), + commits = listOf(CommitNode("0000001", "Add app routes")), + branches = mapOf("master" to 1), + ) + }, validator = commandAnswer("26"), testCases = listOf( levelTestCase("answer changed line", "26"), diff --git a/app/src/test/java/solutions/tretter/githugandroid/GitSandboxEngineTest.kt b/app/src/test/java/solutions/tretter/githugandroid/GitSandboxEngineTest.kt index b013721..fa0a39f 100644 --- a/app/src/test/java/solutions/tretter/githugandroid/GitSandboxEngineTest.kt +++ b/app/src/test/java/solutions/tretter/githugandroid/GitSandboxEngineTest.kt @@ -209,6 +209,29 @@ class GitSandboxEngineTest { } } + @Test + fun nativeDiffLevelShowsLine26Change() { + val git = testGitBinary() + assumeTrue(git.exists() && git.canExecute()) + val root = Files.createTempDirectory("githug-diff-level").toFile() + try { + val runtime = GitRepositoryRuntime(root, git) + val level = diffLevel() + val repo = runtime.prepareLevel(level) + + val appFile = repo.files.single { it.name == "app.rb" } + assertTrue(appFile.content.contains("server.json")) + + val (_, diffOutput) = runtime.execute(level, repo, "git diff") + + assertTrue(diffOutput.any { it.contains("- @message = get_response('data.json')") }) + assertTrue(diffOutput.any { it.contains("+ @message = get_response('server.json')") }) + assertTrue(diffOutput.any { it.contains("@@ -23,7 +23,7 @@") }) + } finally { + root.deleteRecursively() + } + } + @Test fun cdDotDotShortcutMovesToParentDirectory() { val repo = RepoState(initialized = true, currentDir = "src/main")