aboutsummaryrefslogtreecommitdiff
path: root/object/fetch/treefs_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'object/fetch/treefs_test.go')
-rw-r--r--object/fetch/treefs_test.go172
1 files changed, 172 insertions, 0 deletions
diff --git a/object/fetch/treefs_test.go b/object/fetch/treefs_test.go
new file mode 100644
index 00000000..05240823
--- /dev/null
+++ b/object/fetch/treefs_test.go
@@ -0,0 +1,172 @@
+package fetch_test
+
+import (
+ "errors"
+ "io/fs"
+ "testing"
+
+ "lindenii.org/go/furgit/object/commit"
+ "lindenii.org/go/furgit/object/fetch"
+ "lindenii.org/go/furgit/object/id"
+ "lindenii.org/go/furgit/object/signature"
+ "lindenii.org/go/furgit/object/store/memory"
+ "lindenii.org/go/furgit/object/tree"
+ "lindenii.org/go/furgit/object/tree/mode"
+ "lindenii.org/go/furgit/object/typ"
+)
+
+func TestTreeFS(t *testing.T) {
+ t.Parallel()
+
+ for _, objectFormat := range id.SupportedObjectFormats() {
+ t.Run(objectFormat.String(), func(t *testing.T) {
+ t.Parallel()
+
+ store := memory.New(objectFormat)
+
+ plainID, err := store.WriteBytesContent(typ.Blob, []byte("plain\n"))
+ if err != nil {
+ t.Fatalf("WriteBytesContent(plain.txt): %v", err)
+ }
+
+ execID, err := store.WriteBytesContent(typ.Blob, []byte("#!/bin/sh\nexit 0\n"))
+ if err != nil {
+ t.Fatalf("WriteBytesContent(exec.sh): %v", err)
+ }
+
+ subTreeID := writeTree(t, store, []tree.Entry{
+ {Mode: mode.Executable, Name: []byte("exec.sh"), ID: execID},
+ })
+
+ rootTreeID := writeTree(t, store, []tree.Entry{
+ {Mode: mode.Regular, Name: []byte("plain.txt"), ID: plainID},
+ {Mode: mode.Directory, Name: []byte("dir"), ID: subTreeID},
+ })
+
+ commitID := writeCommit(t, store, rootTreeID)
+
+ fetcher := fetch.New(store)
+
+ treeFS, err := fetcher.TreeFS(commitID)
+ if err != nil {
+ t.Fatalf("fetcher.TreeFS: %v", err)
+ }
+
+ content, err := treeFS.ReadFile("plain.txt")
+ if err != nil {
+ t.Fatalf("ReadFile(plain.txt): %v", err)
+ }
+
+ if string(content) != "plain\n" {
+ t.Fatalf("ReadFile(plain.txt) = %q, want %q", string(content), "plain\n")
+ }
+
+ entries, err := treeFS.ReadDir(".")
+ if err != nil {
+ t.Fatalf("ReadDir(.): %v", err)
+ }
+
+ if len(entries) != 2 {
+ t.Fatalf("len(ReadDir(.)) = %d, want 2", len(entries))
+ }
+
+ info, err := treeFS.Stat("plain.txt")
+ if err != nil {
+ t.Fatalf("Stat(plain.txt): %v", err)
+ }
+
+ entry, ok := info.Sys().(tree.Entry)
+ if !ok {
+ t.Fatalf("Stat(plain.txt).Sys() type = %T, want tree.Entry", info.Sys())
+ }
+
+ if entry.Mode != mode.Regular {
+ t.Fatalf("Stat(plain.txt).Sys().Mode = %o, want %o", entry.Mode, mode.Regular)
+ }
+
+ subFS, err := treeFS.Sub("dir")
+ if err != nil {
+ t.Fatalf("Sub(dir): %v", err)
+ }
+
+ subReadFileFS, ok := subFS.(fs.ReadFileFS)
+ if !ok {
+ t.Fatalf("Sub(dir) type does not implement fs.ReadFileFS")
+ }
+
+ subContent, err := subReadFileFS.ReadFile("exec.sh")
+ if err != nil {
+ t.Fatalf("Sub(dir).ReadFile(exec.sh): %v", err)
+ }
+
+ if string(subContent) != "#!/bin/sh\nexit 0\n" {
+ t.Fatalf("Sub(dir).ReadFile(exec.sh) = %q", string(subContent))
+ }
+
+ _, err = treeFS.ReadFile("dir")
+ if err == nil {
+ t.Fatal("ReadFile(dir) unexpectedly succeeded")
+ }
+
+ if _, ok := errors.AsType[*fs.PathError](err); !ok {
+ t.Fatalf("ReadFile(dir) err type = %T, want *fs.PathError", err)
+ }
+ })
+ }
+}
+
+// writeTree builds a tree object from entries, writes it to store,
+// and returns its object ID.
+func writeTree(t *testing.T, store *memory.Memory, entries []tree.Entry) id.ObjectID {
+ t.Helper()
+
+ tr := new(tree.Tree)
+ for _, entry := range entries {
+ err := tr.Insert(entry)
+ if err != nil {
+ t.Fatalf("tree.Insert(%q): %v", entry.Name, err)
+ }
+ }
+
+ body, err := tr.AppendWithoutHeader(nil)
+ if err != nil {
+ t.Fatalf("tree.AppendWithoutHeader: %v", err)
+ }
+
+ treeID, err := store.WriteBytesContent(typ.Tree, body)
+ if err != nil {
+ t.Fatalf("WriteBytesContent(tree): %v", err)
+ }
+
+ return treeID
+}
+
+// writeCommit builds a commit object pointing at tree, writes it to store,
+// and returns its object ID.
+func writeCommit(t *testing.T, store *memory.Memory, tree id.ObjectID) id.ObjectID {
+ t.Helper()
+
+ who := signature.Signature{
+ Name: []byte("Test Author"),
+ Email: []byte("author@example.org"),
+ WhenUnix: 1234567890,
+ OffsetMinutes: 0,
+ }
+
+ body, err := (&commit.Commit{
+ Tree: tree,
+ Author: who,
+ Committer: who,
+ Message: []byte("treefs\n"),
+ }).AppendWithoutHeader(nil)
+ if err != nil {
+ t.Fatalf("commit.AppendWithoutHeader: %v", err)
+ }
+
+ commitID, err := store.WriteBytesContent(typ.Commit, body)
+ if err != nil {
+ t.Fatalf("WriteBytesContent(commit): %v", err)
+ }
+
+ return commitID
+}