add nip34/git-natural-api, using the same approach as https://jsr.io/@fiatjaf/git-natural-api.
This commit is contained in:
@@ -0,0 +1,289 @@
|
||||
package gitnaturalapi
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGetRefs(t *testing.T) {
|
||||
info, err := GetInfoRefs("https://codeberg.org/dluvian/gitplaza.git")
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Contains(t, info.Capabilities, "shallow")
|
||||
require.Contains(t, info.Capabilities, "object-format=sha1")
|
||||
require.Greater(t, len(info.Refs), 5)
|
||||
require.Contains(t, info.Refs, "refs/heads/master")
|
||||
require.Equal(t, "a04d0761564b0d23c5edbadf494ab4f1cc4656f4", info.Refs["refs/tags/v0.1.0"])
|
||||
require.Equal(t, "refs/heads/master", info.Symrefs["HEAD"])
|
||||
}
|
||||
|
||||
func TestGetOnlyTreeAtCurrentCommit(t *testing.T) {
|
||||
urls := []string{
|
||||
"https://codeberg.org/dluvian/gitplaza.git",
|
||||
"https://github.com/fiatjaf/pyramid.git",
|
||||
"https://pyramid.fiatjaf.com/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6/nostrlib.git",
|
||||
}
|
||||
|
||||
for _, url := range urls {
|
||||
t.Run(url, func(t *testing.T) {
|
||||
tree, err := GetDirectoryTreeAt(url, "refs/heads/master", nil)
|
||||
require.NoError(t, err)
|
||||
for _, file := range tree.Files {
|
||||
require.Nil(t, file.Content, "file %q should have nil content at %s", file.Name, url)
|
||||
}
|
||||
require.Greater(t, len(tree.Directories), 2, "at %s", url)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloneRepositoryAtCurrentCommit(t *testing.T) {
|
||||
urls := []string{
|
||||
"https://codeberg.org/dluvian/gitplaza.git",
|
||||
"https://github.com/fiatjaf/pyramid.git",
|
||||
"https://pyramid.fiatjaf.com/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6/nostrlib.git",
|
||||
}
|
||||
|
||||
for _, url := range urls {
|
||||
t.Run(url, func(t *testing.T) {
|
||||
commit, tree, err := ShallowCloneRepositoryAt(url, "refs/heads/master")
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, len(tree.Files), 5, "at %s", url)
|
||||
require.Greater(t, len(tree.Directories), 2, "at %s", url)
|
||||
|
||||
info, err := GetInfoRefs(url)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, info.Refs["refs/heads/master"], commit.Hash, "at %s", url)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSpecificObject(t *testing.T) {
|
||||
url := "https://codeberg.org/dluvian/gitplaza.git"
|
||||
hash := "0f9438a8fd68594cd663fb8dbd23c5f5139f5263" // shell.nix
|
||||
|
||||
blob, err := GetObject(url, hash)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, blob)
|
||||
require.Equal(t, ObjectTypeBlob, blob.Type)
|
||||
|
||||
expected := "(builtins.getFlake\n (\"git+file://\" + toString ./.)).devShells.${builtins.currentSystem}.default\n"
|
||||
require.Equal(t, expected, string(blob.Data))
|
||||
}
|
||||
|
||||
func TestGetNonExistentCommit(t *testing.T) {
|
||||
urls := []string{
|
||||
"https://codeberg.org/dluvian/gitplaza.git",
|
||||
"https://pyramid.fiatjaf.com/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6/nostrlib.git",
|
||||
"https://github.com/fiatjaf/nak.git",
|
||||
}
|
||||
|
||||
commit := "1d4438a8fd68594cd663fb8dbd23c5f5139fabcd" // doesn't exist
|
||||
|
||||
for _, url := range urls {
|
||||
t.Run(url, func(t *testing.T) {
|
||||
_, err := GetDirectoryTreeAt(url, commit, nil)
|
||||
require.Error(t, err)
|
||||
var missingRef *MissingRef
|
||||
require.ErrorAs(t, err, &missingRef)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetchListOfCommits(t *testing.T) {
|
||||
commits, err := FetchCommitsOnly(
|
||||
"https://pyramid.fiatjaf.com/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6/nostrlib.git",
|
||||
"refs/heads/master",
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, len(commits), 10)
|
||||
}
|
||||
|
||||
func TestFetch10PastCommits(t *testing.T) {
|
||||
maxCommits := 10
|
||||
commits, err := FetchCommitsOnly(
|
||||
"https://github.com/fiatjaf/pyramid.git",
|
||||
"57712756e37d7c60d1ac53e0f6b59e9ecad67c9a",
|
||||
&maxCommits,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, commits, 10)
|
||||
|
||||
c := commits[1]
|
||||
require.Equal(t, "49c1b48f5120bad4089535a190d2233c96188fa2", c.Hash)
|
||||
require.Equal(t, "286786a6f1072a2ef5ae057fbb611858b8e88bc4", c.Tree)
|
||||
require.Equal(t, []string{"1599e46c0ee6f460e25048880754868d4f9644fd"}, c.Parents)
|
||||
require.Equal(t, "fiatjaf", c.Author.Name)
|
||||
require.Equal(t, "fiatjaf@gmail.com", c.Author.Email)
|
||||
require.Equal(t, int64(1767157644), c.Author.Timestamp)
|
||||
require.Equal(t, "-0300", c.Author.Timezone)
|
||||
require.Equal(t, "fiatjaf", c.Committer.Name)
|
||||
require.Equal(t, "fiatjaf@gmail.com", c.Committer.Email)
|
||||
require.Equal(t, int64(1767157724), c.Committer.Timestamp)
|
||||
require.Equal(t, "-0300", c.Committer.Timezone)
|
||||
require.Equal(t, "scheduled events.\n", c.Message)
|
||||
|
||||
expectedMsg5 := "turn off groups logic on QueryStore and PreventBroadcast when groups is turned off.\n\nthis was causing crashes that Golang's bizarre iter API showed as happening inside SortedMerge.\n"
|
||||
require.Equal(t, expectedMsg5, commits[5].Message)
|
||||
}
|
||||
|
||||
func TestGetSingleCommit(t *testing.T) {
|
||||
url := "https://github.com/fiatjaf/pyramid.git"
|
||||
commit, err := GetSingleCommit(url, "5e982dd1122a0bb1b0154c222ec4ba841f3820c6")
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, "5e982dd1122a0bb1b0154c222ec4ba841f3820c6", commit.Hash)
|
||||
require.Equal(t, "fiatjaf", commit.Author.Name)
|
||||
require.Equal(t, "validate incoming git-related stuff.\n", commit.Message)
|
||||
}
|
||||
|
||||
func TestGetDirectoryTreeWithDepthLimit(t *testing.T) {
|
||||
url := "https://github.com/fiatjaf/pyramid.git"
|
||||
|
||||
fullTree, err := GetDirectoryTreeAt(url, "refs/heads/master", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
depth := 1
|
||||
shallowTree, err := GetDirectoryTreeAt(url, "refs/heads/master", &depth)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, len(fullTree.Directories), len(shallowTree.Directories))
|
||||
|
||||
for _, dir := range shallowTree.Directories {
|
||||
require.NotNil(t, dir.Content, "directory %q content should not be nil at depth 1", dir.Name)
|
||||
for _, file := range dir.Content.Files {
|
||||
require.NotEmpty(t, file.Name)
|
||||
require.Nil(t, file.Content, "file %q content should be nil", file.Name)
|
||||
}
|
||||
for _, subdir := range dir.Content.Directories {
|
||||
require.NotEmpty(t, subdir.Name)
|
||||
require.Nil(t, subdir.Content, "subdir %q content should be nil at depth 1", subdir.Name)
|
||||
}
|
||||
}
|
||||
|
||||
require.Equal(t, len(fullTree.Files), len(shallowTree.Files))
|
||||
}
|
||||
|
||||
func TestGetObjectByPathExistingFile(t *testing.T) {
|
||||
url := "https://codeberg.org/dluvian/gitplaza.git"
|
||||
entry, err := GetObjectByPath(url, "refs/heads/master", "README.md")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, entry)
|
||||
require.Equal(t, "README.md", entry.Path)
|
||||
require.False(t, entry.IsDir)
|
||||
require.Equal(t, "100644", entry.Mode)
|
||||
require.NotEmpty(t, entry.Hash)
|
||||
}
|
||||
|
||||
func TestGetObjectByPathExistingDirectory(t *testing.T) {
|
||||
url := "https://codeberg.org/dluvian/gitplaza.git"
|
||||
entry, err := GetObjectByPath(url, "refs/heads/master", "src")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, entry)
|
||||
require.Equal(t, "src", entry.Path)
|
||||
require.True(t, entry.IsDir)
|
||||
require.Equal(t, "40000", entry.Mode)
|
||||
require.NotEmpty(t, entry.Hash)
|
||||
}
|
||||
|
||||
func TestGetObjectByPathNestedFile(t *testing.T) {
|
||||
url := "https://github.com/fiatjaf/pyramid.git"
|
||||
entry, err := GetObjectByPath(url, "d567c18cd5c144a58b0214216f454b3caf49d4ff", "grasp/grasp.templ")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, entry)
|
||||
require.Equal(t, "grasp.templ", entry.Path)
|
||||
require.False(t, entry.IsDir)
|
||||
require.Equal(t, "100644", entry.Mode)
|
||||
require.Equal(t, "05bce14339ece5f48c670d0592faa8dece9e8957", entry.Hash)
|
||||
}
|
||||
|
||||
func TestGetObjectByPathNonExistent(t *testing.T) {
|
||||
url := "https://codeberg.org/dluvian/gitplaza.git"
|
||||
entry, err := GetObjectByPath(url, "refs/heads/master", "whatever/something/x/y/z/non-existent-file.txt")
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, entry)
|
||||
}
|
||||
|
||||
func TestGetCommitDiff(t *testing.T) {
|
||||
url := "https://github.com/smallhelm/diff-lines.git"
|
||||
diff, err := GetCommitDiff(url, "a73592653fe9d01f948ca3035e088e45f722eca7")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, diff)
|
||||
require.Len(t, diff, 5)
|
||||
|
||||
byPath := make(map[string]DiffFile, len(diff))
|
||||
for _, f := range diff {
|
||||
byPath[f.Path] = f
|
||||
}
|
||||
|
||||
for _, tc := range []struct {
|
||||
path string
|
||||
status string
|
||||
}{
|
||||
{".travis.yml", "added"},
|
||||
{".gitignore", "added"},
|
||||
{"index.js", "added"},
|
||||
{"tests.js", "added"},
|
||||
{"package.json", "changed"},
|
||||
} {
|
||||
f, ok := byPath[tc.path]
|
||||
require.True(t, ok, "missing diff file %q", tc.path)
|
||||
require.Equal(t, tc.status, f.Status, "%s status", tc.path)
|
||||
}
|
||||
|
||||
gitignore, ok := byPath[".gitignore"]
|
||||
require.True(t, ok, "missing .gitignore in diff")
|
||||
require.Equal(t, "/node_modules\n", string(gitignore.Content))
|
||||
|
||||
pkg, ok := byPath["package.json"]
|
||||
require.True(t, ok, "missing package.json in diff")
|
||||
require.NotEmpty(t, pkg.Lines, "package.json should have diff lines")
|
||||
|
||||
normalizeLineStatus := func(status string) string {
|
||||
if status == "same" {
|
||||
return "changed"
|
||||
}
|
||||
return status
|
||||
}
|
||||
|
||||
lineByIndex := make(map[int]DiffLine, len(pkg.Lines))
|
||||
for _, line := range pkg.Lines {
|
||||
lineByIndex[line.Index] = line
|
||||
}
|
||||
|
||||
expectedLines := []struct {
|
||||
Index int
|
||||
Status string
|
||||
Text string
|
||||
}{
|
||||
{Index: 22, Status: "added", Text: " },"},
|
||||
{Index: 23, Status: "added", Text: " \"homepage\": \"https://github.com/smallhelm/diff-lines#readme\","},
|
||||
{Index: 24, Status: "added", Text: " \"devDependencies\": {"},
|
||||
{Index: 25, Status: "added", Text: " \"tape\": \"^4.6.0\""},
|
||||
{Index: 27, Status: "added", Text: " \"dependencies\": {"},
|
||||
{Index: 28, Status: "added", Text: " \"diff\": \"^2.2.3\""},
|
||||
{Index: 29, Status: "changed", Text: " }"},
|
||||
}
|
||||
|
||||
actualLines := make([]struct {
|
||||
Index int
|
||||
Status string
|
||||
Text string
|
||||
}, 0, len(expectedLines))
|
||||
for _, expected := range expectedLines {
|
||||
line, ok := lineByIndex[expected.Index]
|
||||
require.True(t, ok, "missing package.json diff line %d", expected.Index)
|
||||
actualLines = append(actualLines, struct {
|
||||
Index int
|
||||
Status string
|
||||
Text string
|
||||
}{
|
||||
Index: line.Index,
|
||||
Status: normalizeLineStatus(line.Status),
|
||||
Text: line.Text,
|
||||
})
|
||||
}
|
||||
|
||||
require.Equal(t, expectedLines, actualLines)
|
||||
}
|
||||
Reference in New Issue
Block a user