git_test.go (4479B)
1 package external 2 3 import ( 4 "context" 5 "errors" 6 "os" 7 "os/exec" 8 "path/filepath" 9 "testing" 10 "time" 11 12 "git.prime8.dev/moncheeta/prime8dev/internal/config" 13 ) 14 15 func TestFixRelativePaths(t *testing.T) { 16 tests := []struct { 17 name, in, want string 18 }{ 19 {"relative link", "[docs](docs/setup.md)", "[docs](https://www.prime8.dev/projects/janitor/raw/docs/setup.md)"}, 20 {"dot slash link", "[lic](./LICENSE)", "[lic](https://www.prime8.dev/projects/janitor/raw/LICENSE)"}, 21 {"link with fragment", "[x](./a.md#usage)", "[x](https://www.prime8.dev/projects/janitor/raw/a.md)"}, 22 {"relative image", "", ""}, 23 {"image with title", ``, ``}, 24 {"absolute link", "[site](https://prime8.dev)", "[site](https://prime8.dev)"}, 25 {"http image", "", ""}, 26 {"anchor", "[top](#top)", "[top](#top)"}, 27 {"directory link", "[src](./src/)", "[src](https://www.prime8.dev/projects/janitor)"}, 28 {"mailto", "[mail](mailto:damian@prime8.dev)", "[mail](mailto:damian@prime8.dev)"}, 29 { 30 "linked image", 31 "[](./CONTRIBUTING.md)", 32 "[](https://www.prime8.dev/projects/janitor/raw/CONTRIBUTING.md)", 33 }, 34 } 35 36 for _, tt := range tests { 37 t.Run(tt.name, func(t *testing.T) { 38 if got := fixRelativePaths("janitor", tt.in); got != tt.want { 39 t.Errorf("fixRelativePaths(%q)\n got %q\n want %q", tt.in, got, tt.want) 40 } 41 }) 42 } 43 } 44 45 func TestGitFetchMetadata(t *testing.T) { 46 if _, err := exec.LookPath("git"); err != nil { 47 t.Skip("git not installed") 48 } 49 50 reposDir := t.TempDir() 51 work := t.TempDir() 52 bare := filepath.Join(reposDir, "demo.git") 53 54 run := func(env []string, dir string, args ...string) { 55 t.Helper() 56 cmd := exec.Command("git", args...) 57 cmd.Dir = dir 58 cmd.Env = append(os.Environ(), 59 "GIT_CONFIG_GLOBAL=/dev/null", "GIT_CONFIG_NOSYSTEM=1", 60 "GIT_AUTHOR_NAME=t", "GIT_AUTHOR_EMAIL=t@example.com", 61 "GIT_COMMITTER_NAME=t", "GIT_COMMITTER_EMAIL=t@example.com") 62 cmd.Env = append(cmd.Env, env...) 63 if out, err := cmd.CombinedOutput(); err != nil { 64 t.Fatalf("git %v: %v\n%s", args, err, out) 65 } 66 } 67 68 first := time.Date(2024, 1, 2, 3, 4, 5, 0, time.UTC) 69 last := time.Date(2025, 6, 7, 8, 9, 10, 0, time.UTC) 70 at := func(ts time.Time) []string { 71 d := ts.Format(time.RFC3339) 72 return []string{"GIT_AUTHOR_DATE=" + d, "GIT_COMMITTER_DATE=" + d} 73 } 74 75 run(nil, work, "init", "-q") 76 if err := os.WriteFile(filepath.Join(work, "readme.md"), []byte("# demo\n\n\n"), 0o644); err != nil { 77 t.Fatal(err) 78 } 79 run(nil, work, "add", ".") 80 run(at(first), work, "commit", "-q", "-m", "first") 81 if err := os.WriteFile(filepath.Join(work, "main.go"), []byte("package main\n"), 0o644); err != nil { 82 t.Fatal(err) 83 } 84 run(nil, work, "add", ".") 85 run(at(last), work, "commit", "-q", "-m", "second") 86 run(nil, reposDir, "clone", "-q", "--bare", work, bare) 87 88 t.Setenv("GIT_REPOS_DIR", reposDir) 89 svc := NewGit() 90 91 md, err := svc.FetchMetadata(context.Background(), config.Project{ID: "demo", Repo: "demo"}) 92 if err != nil { 93 t.Fatalf("FetchMetadata: %v", err) 94 } 95 if want := "# demo\n\n\n"; md.Readme != want { 96 t.Errorf("Readme = %q, want %q", md.Readme, want) 97 } 98 if !md.DateCreated.Equal(first) { 99 t.Errorf("DateCreated = %v, want %v", md.DateCreated, first) 100 } 101 project := config.Project{ID: "demo", Repo: "demo"} 102 if got, err := svc.ReadFile(context.Background(), project, "main.go"); err != nil || string(got) != "package main\n" { 103 t.Errorf("ReadFile(main.go) = %q, %v", got, err) 104 } 105 for _, bad := range []string{"", "missing.txt", "../demo.git/config", ".git/config", "a//b"} { 106 if _, err := svc.ReadFile(context.Background(), project, bad); !errors.Is(err, ErrNotFound) { 107 t.Errorf("ReadFile(%q) err = %v, want ErrNotFound", bad, err) 108 } 109 } 110 111 if !md.DateModified.Equal(last) { 112 t.Errorf("DateModified = %v, want %v", md.DateModified, last) 113 } 114 115 if _, err := svc.FetchMetadata(context.Background(), config.Project{ID: "missing", Repo: "missing"}); err == nil { 116 t.Error("expected error for missing repo") 117 } 118 if _, err := svc.FetchMetadata(context.Background(), config.Project{ID: "none"}); err == nil { 119 t.Error("expected error for project without repo") 120 } 121 }