github.com/rogpeppe/go-internal@v1.12.1-0.20240509064211-c8567cf8e95f/txtar/archive_test.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package txtar 6 7 import ( 8 "bytes" 9 "fmt" 10 "reflect" 11 "testing" 12 ) 13 14 var tests = []struct { 15 name string 16 text string 17 parsed *Archive 18 }{ 19 // General test 20 { 21 name: "basic", 22 text: `comment1 23 comment2 24 -- file1 -- 25 File 1 text. 26 -- foo --- 27 More file 1 text. 28 -- file 2 -- 29 File 2 text. 30 -- empty -- 31 -- noNL -- 32 hello world`, 33 parsed: &Archive{ 34 Comment: []byte("comment1\ncomment2\n"), 35 Files: []File{ 36 {"file1", []byte("File 1 text.\n-- foo ---\nMore file 1 text.\n")}, 37 {"file 2", []byte("File 2 text.\n")}, 38 {"empty", []byte{}}, 39 {"noNL", []byte("hello world\n")}, 40 }, 41 }, 42 }, 43 // Test CRLF input 44 { 45 name: "basicCRLF", 46 text: "blah\r\n-- hello --\r\nhello\r\n", 47 parsed: &Archive{ 48 Comment: []byte("blah\r\n"), 49 Files: []File{ 50 {"hello", []byte("hello\r\n")}, 51 }, 52 }, 53 }, 54 } 55 56 func Test(t *testing.T) { 57 for _, tt := range tests { 58 t.Run(tt.name, func(t *testing.T) { 59 a := Parse([]byte(tt.text)) 60 if !reflect.DeepEqual(a, tt.parsed) { 61 t.Fatalf("Parse: wrong output:\nhave:\n%s\nwant:\n%s", shortArchive(a), shortArchive(tt.parsed)) 62 } 63 text := Format(a) 64 a = Parse(text) 65 if !reflect.DeepEqual(a, tt.parsed) { 66 t.Fatalf("Parse after Format: wrong output:\nhave:\n%s\nwant:\n%s", shortArchive(a), shortArchive(tt.parsed)) 67 } 68 }) 69 } 70 } 71 72 func shortArchive(a *Archive) string { 73 var buf bytes.Buffer 74 fmt.Fprintf(&buf, "comment: %q\n", a.Comment) 75 for _, f := range a.Files { 76 fmt.Fprintf(&buf, "file %q: %q\n", f.Name, f.Data) 77 } 78 return buf.String() 79 } 80 81 func TestWrite(t *testing.T) { 82 td := t.TempDir() 83 84 good := &Archive{Files: []File{File{Name: "good.txt"}}} 85 if err := Write(good, td); err != nil { 86 t.Fatalf("expected no error; got %v", err) 87 } 88 89 badRel := &Archive{Files: []File{File{Name: "../bad.txt"}}} 90 want := `"../bad.txt": outside parent directory` 91 if err := Write(badRel, td); err == nil || err.Error() != want { 92 t.Fatalf("expected %v; got %v", want, err) 93 } 94 95 badAbs := &Archive{Files: []File{File{Name: "/bad.txt"}}} 96 want = `"/bad.txt": outside parent directory` 97 if err := Write(badAbs, td); err == nil || err.Error() != want { 98 t.Fatalf("expected %v; got %v", want, err) 99 } 100 } 101 102 var unquoteErrorTests = []struct { 103 testName string 104 data string 105 expectError string 106 }{{ 107 testName: "no final newline", 108 data: ">hello", 109 expectError: `data does not appear to be quoted`, 110 }, { 111 testName: "no initial >", 112 data: "hello\n", 113 expectError: `data does not appear to be quoted`, 114 }} 115 116 func TestUnquote(t *testing.T) { 117 for _, test := range unquoteErrorTests { 118 t.Run(test.testName, func(t *testing.T) { 119 _, err := Unquote([]byte(test.data)) 120 if err == nil { 121 t.Fatalf("unexpected success") 122 } 123 if err.Error() != test.expectError { 124 t.Fatalf("unexpected error; got %q want %q", err, test.expectError) 125 } 126 }) 127 } 128 } 129 130 var quoteTests = []struct { 131 testName string 132 data string 133 expect string 134 expectError string 135 }{{ 136 testName: "empty", 137 data: "", 138 expect: "", 139 }, { 140 testName: "one line", 141 data: "foo\n", 142 expect: ">foo\n", 143 }, { 144 testName: "several lines", 145 data: "foo\nbar\n-- baz --\n", 146 expect: ">foo\n>bar\n>-- baz --\n", 147 }, { 148 testName: "bad data", 149 data: "foo\xff\n", 150 expectError: `data contains non-UTF-8 characters`, 151 }, { 152 testName: "no final newline", 153 data: "foo", 154 expectError: `data has no final newline`, 155 }} 156 157 func TestQuote(t *testing.T) { 158 for _, test := range quoteTests { 159 t.Run(test.testName, func(t *testing.T) { 160 got, err := Quote([]byte(test.data)) 161 if test.expectError != "" { 162 if err == nil { 163 t.Fatalf("unexpected success") 164 } 165 if err.Error() != test.expectError { 166 t.Fatalf("unexpected error; got %q want %q", err, test.expectError) 167 } 168 return 169 } 170 if err != nil { 171 t.Fatalf("quote error: %v", err) 172 } 173 if string(got) != test.expect { 174 t.Fatalf("unexpected result; got %q want %q", got, test.expect) 175 } 176 orig, err := Unquote(got) 177 if err != nil { 178 t.Fatal(err) 179 } 180 if string(orig) != test.data { 181 t.Fatalf("round trip failed; got %q want %q", orig, test.data) 182 } 183 }) 184 } 185 }