asdf/internal/git/git_test.go
DeedleFake 27f44a2dc9 feat(golang-rewrite): rename module and move main pacakge to cmd/asdf
* Replace direct `fmt.Println()` usage in a test with `t.Log()`
* Rename `cmd` to `cli`
* Move asdf command from module root
* Fix some linter warnings, thus enabling some tests that were being skipped
* Fix `Makefile`
* Rename module to `github.com/asdf-vm/asdf`
* Fix `TestGetAllToolsAndVersionsInContent/returns_empty_list_with_found_true_and_no_error_when_empty_content`
* Rewrite `Unique()` to be a bit more straightforwards
* Get workflow checks passing again

toolversions.Unique is ever so slightly faster, technically.

```
goos: linux
goarch: amd64
pkg: github.com/asdf-vm/asdf/internal/toolversions
cpu: AMD Ryzen 9 3900X 12-Core Processor
          │ /tmp/old.txt │            /tmp/new.txt            │
          │    sec/op    │   sec/op     vs base               │
Unique-24    346.5n ± 1%   342.4n ± 1%  -1.17% (p=0.027 n=10)

          │ /tmp/old.txt │          /tmp/new.txt          │
          │     B/op     │    B/op     vs base            │
Unique-24     160.0 ± 0%   160.0 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal

          │ /tmp/old.txt │          /tmp/new.txt          │
          │  allocs/op   │ allocs/op   vs base            │
Unique-24     3.000 ± 0%   3.000 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal
```
2024-12-18 10:22:06 -05:00

201 lines
4.9 KiB
Go

package git
import (
"os"
"path/filepath"
"testing"
"github.com/asdf-vm/asdf/repotest"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/stretchr/testify/assert"
)
func TestPluginClone(t *testing.T) {
t.Run("when plugin name is valid but URL is invalid prints an error", func(t *testing.T) {
plugin := NewRepo(t.TempDir())
err := plugin.Clone("foobar")
assert.ErrorContains(t, err, "unable to clone plugin: repository not found")
})
t.Run("clones provided Git URL to plugin directory when URL is valid", func(t *testing.T) {
repoDir := generateRepo(t)
directory := t.TempDir()
plugin := NewRepo(directory)
err := plugin.Clone(repoDir)
assert.Nil(t, err)
// Assert plugin directory contains Git repo with bin directory
_, err = os.ReadDir(directory + "/.git")
assert.Nil(t, err)
entries, err := os.ReadDir(directory + "/bin")
assert.Nil(t, err)
assert.Equal(t, 12, len(entries))
})
}
func TestPluginHead(t *testing.T) {
repoDir := generateRepo(t)
directory := t.TempDir()
plugin := NewRepo(directory)
err := plugin.Clone(repoDir)
assert.Nil(t, err)
head, err := plugin.Head()
assert.Nil(t, err)
assert.NotZero(t, head)
}
func TestPluginRemoteURL(t *testing.T) {
repoDir := generateRepo(t)
directory := t.TempDir()
plugin := NewRepo(directory)
err := plugin.Clone(repoDir)
assert.Nil(t, err)
url, err := plugin.RemoteURL()
assert.Nil(t, err)
assert.NotZero(t, url)
}
func TestPluginUpdate(t *testing.T) {
repoDir := generateRepo(t)
directory := t.TempDir()
plugin := NewRepo(directory)
err := plugin.Clone(repoDir)
assert.Nil(t, err)
t.Run("returns error when plugin with name does not exist", func(t *testing.T) {
nonexistantPath := filepath.Join(directory, "nonexistant")
nonexistantPlugin := NewRepo(nonexistantPath)
updatedToRef, err := nonexistantPlugin.Update("")
assert.NotNil(t, err)
assert.Equal(t, updatedToRef, "")
expectedErrMsg := "unable to open plugin Git repository: repository does not exist"
assert.ErrorContains(t, err, expectedErrMsg)
})
t.Run("returns error when plugin repo does not exist", func(t *testing.T) {
badPluginName := "badplugin"
badPluginDir := filepath.Join(directory, badPluginName)
err := os.MkdirAll(badPluginDir, 0o777)
assert.Nil(t, err)
badPlugin := NewRepo(badPluginDir)
updatedToRef, err := badPlugin.Update("")
assert.NotNil(t, err)
assert.Equal(t, updatedToRef, "")
expectedErrMsg := "unable to open plugin Git repository: repository does not exist"
assert.ErrorContains(t, err, expectedErrMsg)
})
t.Run("does not return error when plugin is already updated", func(t *testing.T) {
// update plugin twice to test already updated case
updatedToRef, err := plugin.Update("")
assert.Nil(t, err)
updatedToRef2, err := plugin.Update("")
assert.Nil(t, err)
assert.Equal(t, updatedToRef, updatedToRef2)
})
t.Run("updates plugin when plugin when plugin exists", func(t *testing.T) {
latestHash, err := getCurrentCommit(directory)
assert.Nil(t, err)
_, err = checkoutPreviousCommit(directory)
assert.Nil(t, err)
updatedToRef, err := plugin.Update("")
assert.Nil(t, err)
assert.Equal(t, latestHash, updatedToRef)
currentHash, err := getCurrentCommit(directory)
assert.Nil(t, err)
assert.Equal(t, latestHash, currentHash)
})
t.Run("Returns error when specified ref does not exist", func(t *testing.T) {
ref := "non-existant"
updatedToRef, err := plugin.Update(ref)
assert.Equal(t, updatedToRef, "")
expectedErrMsg := "couldn't find remote ref \"non-existant\""
assert.ErrorContains(t, err, expectedErrMsg)
})
t.Run("updates plugin to ref when plugin with name and ref exist", func(t *testing.T) {
ref := "master"
hash, err := getCommit(directory, ref)
assert.Nil(t, err)
updatedToRef, err := plugin.Update(ref)
assert.Nil(t, err)
assert.Equal(t, hash, updatedToRef)
// Check that plugin was updated to ref
latestHash, err := getCurrentCommit(directory)
assert.Nil(t, err)
assert.Equal(t, hash, latestHash)
})
}
func getCurrentCommit(path string) (string, error) {
return getCommit(path, "HEAD")
}
func getCommit(path, revision string) (string, error) {
repo, err := git.PlainOpen(path)
if err != nil {
return "", err
}
hash, err := repo.ResolveRevision(plumbing.Revision(revision))
return hash.String(), err
}
func checkoutPreviousCommit(path string) (string, error) {
repo, err := git.PlainOpen(path)
if err != nil {
return "", err
}
previousHash, err := repo.ResolveRevision(plumbing.Revision("HEAD~"))
if err != nil {
return "", err
}
worktree, err := repo.Worktree()
if err != nil {
return "", err
}
err = worktree.Reset(&git.ResetOptions{Commit: *previousHash})
if err != nil {
return "", err
}
return previousHash.String(), nil
}
func generateRepo(t *testing.T) string {
t.Helper()
tempDir := t.TempDir()
path, err := repotest.GeneratePlugin("dummy_plugin", tempDir, "lua")
assert.Nil(t, err)
return path
}