|
|
@@ -6,7 +6,11 @@ package webdav
|
|
|
|
|
|
import (
|
|
|
"fmt"
|
|
|
+ "io"
|
|
|
+ "io/ioutil"
|
|
|
+ "os"
|
|
|
"path/filepath"
|
|
|
+ "strconv"
|
|
|
"strings"
|
|
|
"testing"
|
|
|
)
|
|
|
@@ -193,3 +197,202 @@ func TestWalk(t *testing.T) {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+func TestMemFile(t *testing.T) {
|
|
|
+ testCases := []string{
|
|
|
+ "wantData ",
|
|
|
+ "wantSize 0",
|
|
|
+ "write abc",
|
|
|
+ "wantData abc",
|
|
|
+ "write de",
|
|
|
+ "wantData abcde",
|
|
|
+ "wantSize 5",
|
|
|
+ "write 5*x",
|
|
|
+ "write 4*y+2*z",
|
|
|
+ "write 3*st",
|
|
|
+ "wantData abcdexxxxxyyyyzzststst",
|
|
|
+ "wantSize 22",
|
|
|
+ "seek set 4 want 4",
|
|
|
+ "write EFG",
|
|
|
+ "wantData abcdEFGxxxyyyyzzststst",
|
|
|
+ "wantSize 22",
|
|
|
+ "seek set 2 want 2",
|
|
|
+ "read cdEF",
|
|
|
+ "read Gx",
|
|
|
+ "seek cur 0 want 8",
|
|
|
+ "seek cur 2 want 10",
|
|
|
+ "seek cur -1 want 9",
|
|
|
+ "write J",
|
|
|
+ "wantData abcdEFGxxJyyyyzzststst",
|
|
|
+ "wantSize 22",
|
|
|
+ "seek cur -4 want 6",
|
|
|
+ "write ghijk",
|
|
|
+ "wantData abcdEFghijkyyyzzststst",
|
|
|
+ "wantSize 22",
|
|
|
+ "read yyyz",
|
|
|
+ "seek cur 0 want 15",
|
|
|
+ "write ",
|
|
|
+ "seek cur 0 want 15",
|
|
|
+ "read ",
|
|
|
+ "seek cur 0 want 15",
|
|
|
+ "seek end -3 want 19",
|
|
|
+ "write ZZ",
|
|
|
+ "wantData abcdEFghijkyyyzzstsZZt",
|
|
|
+ "wantSize 22",
|
|
|
+ "write 4*A",
|
|
|
+ "wantData abcdEFghijkyyyzzstsZZAAAA",
|
|
|
+ "wantSize 25",
|
|
|
+ "seek end 0 want 25",
|
|
|
+ "seek end -5 want 20",
|
|
|
+ "read Z+4*A",
|
|
|
+ "write 5*B",
|
|
|
+ "wantData abcdEFghijkyyyzzstsZZAAAABBBBB",
|
|
|
+ "wantSize 30",
|
|
|
+ "seek end 10 want 40",
|
|
|
+ "write C",
|
|
|
+ "wantData abcdEFghijkyyyzzstsZZAAAABBBBB..........C",
|
|
|
+ "wantSize 41",
|
|
|
+ "seek set 43 want 43",
|
|
|
+ "write D",
|
|
|
+ "wantData abcdEFghijkyyyzzstsZZAAAABBBBB..........C..D",
|
|
|
+ "wantSize 44",
|
|
|
+ "seek set 0 want 0",
|
|
|
+ "write 5*123456789_",
|
|
|
+ "wantData 123456789_123456789_123456789_123456789_123456789_",
|
|
|
+ "wantSize 50",
|
|
|
+ "seek cur 0 want 50",
|
|
|
+ "seek cur -99 want err",
|
|
|
+ }
|
|
|
+
|
|
|
+ const filename = "/foo"
|
|
|
+ fs := NewMemFS()
|
|
|
+ f, err := fs.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("OpenFile: %v", err)
|
|
|
+ }
|
|
|
+ defer f.Close()
|
|
|
+
|
|
|
+ for i, tc := range testCases {
|
|
|
+ j := strings.IndexByte(tc, ' ')
|
|
|
+ if j < 0 {
|
|
|
+ t.Fatalf("test case #%d %q: invalid command", i, tc)
|
|
|
+ }
|
|
|
+ op, arg := tc[:j], tc[j+1:]
|
|
|
+
|
|
|
+ // Expand an arg like "3*a+2*b" to "aaabb".
|
|
|
+ parts := strings.Split(arg, "+")
|
|
|
+ for j, part := range parts {
|
|
|
+ if k := strings.IndexByte(part, '*'); k >= 0 {
|
|
|
+ repeatCount, repeatStr := part[:k], part[k+1:]
|
|
|
+ n, err := strconv.Atoi(repeatCount)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("test case #%d %q: invalid repeat count %q", i, tc, repeatCount)
|
|
|
+ }
|
|
|
+ parts[j] = strings.Repeat(repeatStr, n)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ arg = strings.Join(parts, "")
|
|
|
+
|
|
|
+ switch op {
|
|
|
+ default:
|
|
|
+ t.Fatalf("test case #%d %q: invalid operation %q", i, tc, op)
|
|
|
+
|
|
|
+ case "read":
|
|
|
+ buf := make([]byte, len(arg))
|
|
|
+ if _, err := io.ReadFull(f, buf); err != nil {
|
|
|
+ t.Fatalf("test case #%d %q: ReadFull: %v", i, tc, err)
|
|
|
+ }
|
|
|
+ if got := string(buf); got != arg {
|
|
|
+ t.Fatalf("test case #%d %q:\ngot %q\nwant %q", i, tc, got, arg)
|
|
|
+ }
|
|
|
+
|
|
|
+ case "seek":
|
|
|
+ parts := strings.Split(arg, " ")
|
|
|
+ if len(parts) != 4 {
|
|
|
+ t.Fatalf("test case #%d %q: invalid seek", i, tc)
|
|
|
+ }
|
|
|
+
|
|
|
+ whence := 0
|
|
|
+ switch parts[0] {
|
|
|
+ default:
|
|
|
+ t.Fatalf("test case #%d %q: invalid seek whence", i, tc)
|
|
|
+ case "set":
|
|
|
+ whence = os.SEEK_SET
|
|
|
+ case "cur":
|
|
|
+ whence = os.SEEK_CUR
|
|
|
+ case "end":
|
|
|
+ whence = os.SEEK_END
|
|
|
+ }
|
|
|
+ offset, err := strconv.Atoi(parts[1])
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("test case #%d %q: invalid offset %q", i, tc, parts[1])
|
|
|
+ }
|
|
|
+
|
|
|
+ if parts[2] != "want" {
|
|
|
+ t.Fatalf("test case #%d %q: invalid seek", i, tc)
|
|
|
+ }
|
|
|
+ if parts[3] == "err" {
|
|
|
+ _, err := f.Seek(int64(offset), whence)
|
|
|
+ if err == nil {
|
|
|
+ t.Fatalf("test case #%d %q: Seek returned nil error, want non-nil", i, tc)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ got, err := f.Seek(int64(offset), whence)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("test case #%d %q: Seek: %v", i, tc, err)
|
|
|
+ }
|
|
|
+ want, err := strconv.Atoi(parts[3])
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("test case #%d %q: invalid want %q", i, tc, parts[3])
|
|
|
+ }
|
|
|
+ if got != int64(want) {
|
|
|
+ t.Fatalf("test case #%d %q: got %d, want %d", i, tc, got, want)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ case "write":
|
|
|
+ n, err := f.Write([]byte(arg))
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("test case #%d %q: write: %v", i, tc, err)
|
|
|
+ }
|
|
|
+ if n != len(arg) {
|
|
|
+ t.Fatalf("test case #%d %q: write returned %d bytes, want %d", i, tc, n, len(arg))
|
|
|
+ }
|
|
|
+
|
|
|
+ case "wantData":
|
|
|
+ g, err := fs.OpenFile(filename, os.O_RDONLY, 0666)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("test case #%d %q: OpenFile: %v", i, tc, err)
|
|
|
+ }
|
|
|
+ gotBytes, err := ioutil.ReadAll(g)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("test case #%d %q: ReadAll: %v", i, tc, err)
|
|
|
+ }
|
|
|
+ for i, c := range gotBytes {
|
|
|
+ if c == '\x00' {
|
|
|
+ gotBytes[i] = '.'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ got := string(gotBytes)
|
|
|
+ if got != arg {
|
|
|
+ t.Fatalf("test case #%d %q:\ngot %q\nwant %q", i, tc, got, arg)
|
|
|
+ }
|
|
|
+ if err := g.Close(); err != nil {
|
|
|
+ t.Fatalf("test case #%d %q: Close: %v", i, tc, err)
|
|
|
+ }
|
|
|
+
|
|
|
+ case "wantSize":
|
|
|
+ n, err := strconv.Atoi(arg)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("test case #%d %q: invalid size %q", i, tc, arg)
|
|
|
+ }
|
|
|
+ fi, err := fs.Stat(filename)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("test case #%d %q: Stat: %v", i, tc, err)
|
|
|
+ }
|
|
|
+ if got, want := fi.Size(), int64(n); got != want {
|
|
|
+ t.Fatalf("test case #%d %q: got %d, want %d", i, tc, got, want)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|