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