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