git-lfs/git/odb/tree_test.go

205 lines
5.0 KiB
Go
Raw Normal View History

2017-05-15 21:59:55 +00:00
package odb
import (
"bufio"
2017-05-15 21:59:55 +00:00
"bytes"
"fmt"
"sort"
2017-05-15 21:59:55 +00:00
"strconv"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestTreeReturnsCorrectObjectType(t *testing.T) {
assert.Equal(t, TreeObjectType, new(Tree).Type())
}
func TestTreeEncoding(t *testing.T) {
tree := &Tree{
Entries: []*TreeEntry{
{
Name: "a.dat",
Oid: []byte("aaaaaaaaaaaaaaaaaaaa"),
Filemode: 0100644,
},
{
Name: "subdir",
Oid: []byte("bbbbbbbbbbbbbbbbbbbb"),
Filemode: 040000,
},
{
Name: "submodule",
Oid: []byte("cccccccccccccccccccc"),
Filemode: 0160000,
},
2017-05-15 21:59:55 +00:00
},
}
buf := new(bytes.Buffer)
n, err := tree.Encode(buf)
assert.Nil(t, err)
assert.NotEqual(t, 0, n)
assertTreeEntry(t, buf, "a.dat", []byte("aaaaaaaaaaaaaaaaaaaa"), 0100644)
assertTreeEntry(t, buf, "subdir", []byte("bbbbbbbbbbbbbbbbbbbb"), 040000)
assertTreeEntry(t, buf, "submodule", []byte("cccccccccccccccccccc"), 0160000)
2017-05-15 21:59:55 +00:00
assert.Equal(t, 0, buf.Len())
}
func TestTreeDecoding(t *testing.T) {
from := new(bytes.Buffer)
fmt.Fprintf(from, "%s %s\x00%s",
strconv.FormatInt(int64(0100644), 8),
"a.dat", []byte("aaaaaaaaaaaaaaaaaaaa"))
fmt.Fprintf(from, "%s %s\x00%s",
strconv.FormatInt(int64(040000), 8),
"subdir", []byte("bbbbbbbbbbbbbbbbbbbb"))
fmt.Fprintf(from, "%s %s\x00%s",
strconv.FormatInt(int64(0120000), 8),
"symlink", []byte("cccccccccccccccccccc"))
fmt.Fprintf(from, "%s %s\x00%s",
strconv.FormatInt(int64(0160000), 8),
"submodule", []byte("dddddddddddddddddddd"))
2017-05-15 21:59:55 +00:00
flen := from.Len()
tree := new(Tree)
n, err := tree.Decode(from, int64(flen))
assert.Nil(t, err)
assert.Equal(t, flen, n)
require.Equal(t, 4, len(tree.Entries))
2017-05-15 21:59:55 +00:00
assert.Equal(t, &TreeEntry{
Name: "a.dat",
Oid: []byte("aaaaaaaaaaaaaaaaaaaa"),
Filemode: 0100644,
}, tree.Entries[0])
assert.Equal(t, &TreeEntry{
Name: "subdir",
Oid: []byte("bbbbbbbbbbbbbbbbbbbb"),
Filemode: 040000,
}, tree.Entries[1])
assert.Equal(t, &TreeEntry{
Name: "symlink",
Oid: []byte("cccccccccccccccccccc"),
Filemode: 0120000,
}, tree.Entries[2])
assert.Equal(t, &TreeEntry{
Name: "submodule",
Oid: []byte("dddddddddddddddddddd"),
Filemode: 0160000,
}, tree.Entries[3])
2017-05-15 21:59:55 +00:00
}
func TestTreeDecodingShaBoundary(t *testing.T) {
var from bytes.Buffer
fmt.Fprintf(&from, "%s %s\x00%s",
strconv.FormatInt(int64(0100644), 8),
"a.dat", []byte("aaaaaaaaaaaaaaaaaaaa"))
flen := from.Len()
tree := new(Tree)
n, err := tree.Decode(bufio.NewReaderSize(&from, flen-2), int64(flen))
assert.Nil(t, err)
assert.Equal(t, flen, n)
require.Len(t, tree.Entries, 1)
assert.Equal(t, &TreeEntry{
Name: "a.dat",
Oid: []byte("aaaaaaaaaaaaaaaaaaaa"),
Filemode: 0100644,
}, tree.Entries[0])
}
type TreeEntryTypeTestCase struct {
Filemode int32
Expected ObjectType
}
func (c *TreeEntryTypeTestCase) Assert(t *testing.T) {
e := &TreeEntry{Filemode: c.Filemode}
got := e.Type()
assert.Equal(t, c.Expected, got,
"git/odb: expected type: %s, got: %s", c.Expected, got)
}
func TestTreeEntryTypeResolution(t *testing.T) {
for desc, c := range map[string]*TreeEntryTypeTestCase{
"blob": {0100644, BlobObjectType},
"subtree": {040000, TreeObjectType},
"symlink": {0120000, BlobObjectType},
"commit": {0160000, CommitObjectType},
} {
t.Run(desc, c.Assert)
}
}
func TestTreeEntryTypeResolutionUnknown(t *testing.T) {
e := &TreeEntry{Filemode: -1}
defer func() {
if err := recover(); err == nil {
t.Fatal("git/odb: expected panic(), got none")
} else {
assert.Equal(t, "git/odb: unknown object type: -1", err)
}
}()
e.Type()
}
func TestSubtreeOrder(t *testing.T) {
// The below list (e1, e2, ..., e5) is entered in subtree order: that
// is, lexicographically byte-ordered as if blobs end in a '\0', and
// sub-trees end in a '/'.
//
// See:
// http://public-inbox.org/git/7vac6jfzem.fsf@assigned-by-dhcp.cox.net
e1 := &TreeEntry{Filemode: 100644, Name: "a-"}
e2 := &TreeEntry{Filemode: 100644, Name: "a-b"}
e3 := &TreeEntry{Filemode: 040000, Name: "a"}
e4 := &TreeEntry{Filemode: 100644, Name: "a="}
e5 := &TreeEntry{Filemode: 100644, Name: "a=b"}
// Create a set of entries in the wrong order:
entries := []*TreeEntry{e3, e4, e1, e5, e2}
sort.Sort(SubtreeOrder(entries))
// Assert that they are in the correct order after sorting in sub-tree
// order:
require.Len(t, entries, 5)
assert.Equal(t, "a-", entries[0].Name)
assert.Equal(t, "a-b", entries[1].Name)
assert.Equal(t, "a", entries[2].Name)
assert.Equal(t, "a=", entries[3].Name)
assert.Equal(t, "a=b", entries[4].Name)
}
2017-05-15 21:59:55 +00:00
func assertTreeEntry(t *testing.T, buf *bytes.Buffer,
name string, oid []byte, mode int32) {
2017-05-15 21:59:55 +00:00
fmode, err := buf.ReadBytes(' ')
assert.Nil(t, err)
assert.Equal(t, []byte(strconv.FormatInt(int64(mode), 8)+" "), fmode)
fname, err := buf.ReadBytes('\x00')
assert.Nil(t, err)
assert.Equal(t, []byte(name+"\x00"), fname)
var sha [20]byte
_, err = buf.Read(sha[:])
assert.Nil(t, err)
assert.Equal(t, oid, sha[:])
}