TestRangeDiffDetectsRename guards against issue #99: when a file is renamed on the target branch, `ocr review --from master --to BRANCH` must recognize the rename and read content at the NEW path. Before the fix the rename could surface as delete(old)+add(new) (e.g. diff.renames=false) and the parse
(t *testing.T)
| 388 | // broken /dev/null detection sent the deleted half into `git show ref:oldpath` |
| 389 | // -> "WARNING: cannot read file ... exit status 128". |
| 390 | func TestRangeDiffDetectsRename(t *testing.T) { |
| 391 | repo := initRepoWithChange(t) |
| 392 | |
| 393 | // Reset the working-tree modification left by the helper. |
| 394 | runGitTest(t, repo, "checkout", "--", "sample.txt") |
| 395 | // Simulate a user config where git does NOT detect renames on its own; |
| 396 | // the provider must force --find-renames. |
| 397 | runGitTest(t, repo, "config", "diff.renames", "false") |
| 398 | |
| 399 | // Commit a file large enough for git's similarity detection to work |
| 400 | // (tiny files fall below the rename threshold even for 1-line edits). |
| 401 | var content strings.Builder |
| 402 | for i := 1; i <= 50; i++ { |
| 403 | fmt.Fprintf(&content, "line%d\n", i) |
| 404 | } |
| 405 | orig := filepath.Join(repo, "orig.txt") |
| 406 | if err := os.WriteFile(orig, []byte(content.String()), 0o644); err != nil { |
| 407 | t.Fatalf("write orig.txt: %v", err) |
| 408 | } |
| 409 | runGitTest(t, repo, "add", "orig.txt") |
| 410 | runGitTest(t, repo, "commit", "-q", "-m", "add orig.txt") |
| 411 | |
| 412 | // Rename on a feature branch, with a small edit (like the issue repro). |
| 413 | runGitTest(t, repo, "checkout", "-q", "-b", "feature") |
| 414 | runGitTest(t, repo, "mv", "orig.txt", "renamed.txt") |
| 415 | edited := strings.Replace(content.String(), "line25\n", "line25-edited\n", 1) |
| 416 | if err := os.WriteFile(filepath.Join(repo, "renamed.txt"), []byte(edited), 0o644); err != nil { |
| 417 | t.Fatalf("edit renamed.txt: %v", err) |
| 418 | } |
| 419 | runGitTest(t, repo, "add", "-A") |
| 420 | runGitTest(t, repo, "commit", "-q", "-m", "rename orig.txt") |
| 421 | |
| 422 | runner := gitcmd.New(0) |
| 423 | provider := NewProvider(repo, "HEAD~1", "feature", runner) |
| 424 | |
| 425 | diffs, err := provider.GetDiff(context.Background()) |
| 426 | if err != nil { |
| 427 | t.Fatalf("GetDiff (range, rename) returned error: %v", err) |
| 428 | } |
| 429 | if len(diffs) != 1 { |
| 430 | t.Fatalf("expected exactly 1 diff for a rename, got %d: %+v", len(diffs), diffs) |
| 431 | } |
| 432 | d := diffs[0] |
| 433 | if !d.IsRenamed { |
| 434 | t.Errorf("IsRenamed = false, want true") |
| 435 | } |
| 436 | if d.OldPath != "orig.txt" || d.NewPath != "renamed.txt" { |
| 437 | t.Errorf("OldPath/NewPath = %q/%q, want orig.txt/renamed.txt", d.OldPath, d.NewPath) |
| 438 | } |
| 439 | if d.NewFileContent == "" { |
| 440 | t.Errorf("NewFileContent is empty: content at new path was not read at ref") |
| 441 | } |
| 442 | } |
| 443 | |
| 444 | // TestRangeDiffSurvivesExternalDiffTool covers the ModeRange call site |
| 445 | // (git diff <base> <to>), which likewise must pass --no-ext-diff so that a |
nothing calls this directly
no test coverage detected