OSDN Git Service

Update Go library to last weekly.
[pf3gnuchains/gcc-fork.git] / libgo / go / csv / reader_test.go
1 // Copyright 2011 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 csv
6
7 import (
8         "reflect"
9         "strings"
10         "testing"
11 )
12
13 var readTests = []struct {
14         Name               string
15         Input              string
16         Output             [][]string
17         UseFieldsPerRecord bool // false (default) means FieldsPerRecord is -1
18
19         // These fields are copied into the Reader
20         Comma            int
21         Comment          int
22         FieldsPerRecord  int
23         LazyQuotes       bool
24         TrailingComma    bool
25         TrimLeadingSpace bool
26
27         Error  string
28         Line   int // Expected error line if != 0
29         Column int // Expected error column if line != 0
30 }{
31         {
32                 Name:   "Simple",
33                 Input:  "a,b,c\n",
34                 Output: [][]string{{"a", "b", "c"}},
35         },
36         {
37                 Name:   "CRLF",
38                 Input:  "a,b\r\nc,d\r\n",
39                 Output: [][]string{{"a", "b"}, {"c", "d"}},
40         },
41         {
42                 Name:   "BareCR",
43                 Input:  "a,b\rc,d\r\n",
44                 Output: [][]string{{"a", "b\rc", "d"}},
45         },
46         {
47                 Name:               "RFC4180test",
48                 UseFieldsPerRecord: true,
49                 Input: `#field1,field2,field3
50 "aaa","bb
51 b","ccc"
52 "a,a","b""bb","ccc"
53 zzz,yyy,xxx
54 `,
55                 Output: [][]string{
56                         {"#field1", "field2", "field3"},
57                         {"aaa", "bb\nb", "ccc"},
58                         {"a,a", `b"bb`, "ccc"},
59                         {"zzz", "yyy", "xxx"},
60                 },
61         },
62         {
63                 Name:   "NoEOLTest",
64                 Input:  "a,b,c",
65                 Output: [][]string{{"a", "b", "c"}},
66         },
67         {
68                 Name:   "Semicolon",
69                 Comma:  ';',
70                 Input:  "a;b;c\n",
71                 Output: [][]string{{"a", "b", "c"}},
72         },
73         {
74                 Name: "MultiLine",
75                 Input: `"two
76 line","one line","three
77 line
78 field"`,
79                 Output: [][]string{{"two\nline", "one line", "three\nline\nfield"}},
80         },
81         {
82                 Name:  "BlankLine",
83                 Input: "a,b,c\n\nd,e,f\n\n",
84                 Output: [][]string{
85                         {"a", "b", "c"},
86                         {"d", "e", "f"},
87                 },
88         },
89         {
90                 Name:             "TrimSpace",
91                 Input:            " a,  b,   c\n",
92                 TrimLeadingSpace: true,
93                 Output:           [][]string{{"a", "b", "c"}},
94         },
95         {
96                 Name:   "LeadingSpace",
97                 Input:  " a,  b,   c\n",
98                 Output: [][]string{{" a", "  b", "   c"}},
99         },
100         {
101                 Name:    "Comment",
102                 Comment: '#',
103                 Input:   "#1,2,3\na,b,c\n#comment",
104                 Output:  [][]string{{"a", "b", "c"}},
105         },
106         {
107                 Name:   "NoComment",
108                 Input:  "#1,2,3\na,b,c",
109                 Output: [][]string{{"#1", "2", "3"}, {"a", "b", "c"}},
110         },
111         {
112                 Name:       "LazyQuotes",
113                 LazyQuotes: true,
114                 Input:      `a "word","1"2",a","b`,
115                 Output:     [][]string{{`a "word"`, `1"2`, `a"`, `b`}},
116         },
117         {
118                 Name:       "BareQuotes",
119                 LazyQuotes: true,
120                 Input:      `a "word","1"2",a"`,
121                 Output:     [][]string{{`a "word"`, `1"2`, `a"`}},
122         },
123         {
124                 Name:       "BareDoubleQuotes",
125                 LazyQuotes: true,
126                 Input:      `a""b,c`,
127                 Output:     [][]string{{`a""b`, `c`}},
128         },
129         {
130                 Name:  "BadDoubleQuotes",
131                 Input: `a""b,c`,
132                 Error: `bare " in non-quoted-field`, Line: 1, Column: 1,
133         },
134         {
135                 Name:             "TrimQuote",
136                 Input:            ` "a"," b",c`,
137                 TrimLeadingSpace: true,
138                 Output:           [][]string{{"a", " b", "c"}},
139         },
140         {
141                 Name:  "BadBareQuote",
142                 Input: `a "word","b"`,
143                 Error: `bare " in non-quoted-field`, Line: 1, Column: 2,
144         },
145         {
146                 Name:  "BadTrailingQuote",
147                 Input: `"a word",b"`,
148                 Error: `bare " in non-quoted-field`, Line: 1, Column: 10,
149         },
150         {
151                 Name:  "ExtraneousQuote",
152                 Input: `"a "word","b"`,
153                 Error: `extraneous " in field`, Line: 1, Column: 3,
154         },
155         {
156                 Name:               "BadFieldCount",
157                 UseFieldsPerRecord: true,
158                 Input:              "a,b,c\nd,e",
159                 Error:              "wrong number of fields", Line: 2,
160         },
161         {
162                 Name:               "BadFieldCount1",
163                 UseFieldsPerRecord: true,
164                 FieldsPerRecord:    2,
165                 Input:              `a,b,c`,
166                 Error:              "wrong number of fields", Line: 1,
167         },
168         {
169                 Name:   "FieldCount",
170                 Input:  "a,b,c\nd,e",
171                 Output: [][]string{{"a", "b", "c"}, {"d", "e"}},
172         },
173         {
174                 Name:  "BadTrailingCommaEOF",
175                 Input: "a,b,c,",
176                 Error: "extra delimiter at end of line", Line: 1, Column: 5,
177         },
178         {
179                 Name:  "BadTrailingCommaEOL",
180                 Input: "a,b,c,\n",
181                 Error: "extra delimiter at end of line", Line: 1, Column: 5,
182         },
183         {
184                 Name:             "BadTrailingCommaSpaceEOF",
185                 TrimLeadingSpace: true,
186                 Input:            "a,b,c, ",
187                 Error:            "extra delimiter at end of line", Line: 1, Column: 5,
188         },
189         {
190                 Name:             "BadTrailingCommaSpaceEOL",
191                 TrimLeadingSpace: true,
192                 Input:            "a,b,c, \n",
193                 Error:            "extra delimiter at end of line", Line: 1, Column: 5,
194         },
195         {
196                 Name:             "BadTrailingCommaLine3",
197                 TrimLeadingSpace: true,
198                 Input:            "a,b,c\nd,e,f\ng,hi,",
199                 Error:            "extra delimiter at end of line", Line: 3, Column: 4,
200         },
201         {
202                 Name:   "NotTrailingComma3",
203                 Input:  "a,b,c, \n",
204                 Output: [][]string{{"a", "b", "c", " "}},
205         },
206         {
207                 Name:          "CommaFieldTest",
208                 TrailingComma: true,
209                 Input: `x,y,z,w
210 x,y,z,
211 x,y,,
212 x,,,
213 ,,,
214 "x","y","z","w"
215 "x","y","z",""
216 "x","y","",""
217 "x","","",""
218 "","","",""
219 `,
220                 Output: [][]string{
221                         {"x", "y", "z", "w"},
222                         {"x", "y", "z", ""},
223                         {"x", "y", "", ""},
224                         {"x", "", "", ""},
225                         {"", "", "", ""},
226                         {"x", "y", "z", "w"},
227                         {"x", "y", "z", ""},
228                         {"x", "y", "", ""},
229                         {"x", "", "", ""},
230                         {"", "", "", ""},
231                 },
232         },
233         {
234                 Name:             "Issue 2366",
235                 TrailingComma:    true,
236                 TrimLeadingSpace: true,
237                 Input:            "a,b,\nc,d,e",
238                 Output: [][]string{
239                         {"a", "b", ""},
240                         {"c", "d", "e"},
241                 },
242         },
243         {
244                 Name:             "Issue 2366a",
245                 TrailingComma:    false,
246                 TrimLeadingSpace: true,
247                 Input:            "a,b,\nc,d,e",
248                 Error:            "extra delimiter at end of line",
249         },
250 }
251
252 func TestRead(t *testing.T) {
253         for _, tt := range readTests {
254                 r := NewReader(strings.NewReader(tt.Input))
255                 r.Comment = tt.Comment
256                 if tt.UseFieldsPerRecord {
257                         r.FieldsPerRecord = tt.FieldsPerRecord
258                 } else {
259                         r.FieldsPerRecord = -1
260                 }
261                 r.LazyQuotes = tt.LazyQuotes
262                 r.TrailingComma = tt.TrailingComma
263                 r.TrimLeadingSpace = tt.TrimLeadingSpace
264                 if tt.Comma != 0 {
265                         r.Comma = tt.Comma
266                 }
267                 out, err := r.ReadAll()
268                 perr, _ := err.(*ParseError)
269                 if tt.Error != "" {
270                         if err == nil || !strings.Contains(err.String(), tt.Error) {
271                                 t.Errorf("%s: error %v, want error %q", tt.Name, err, tt.Error)
272                         } else if tt.Line != 0 && (tt.Line != perr.Line || tt.Column != perr.Column) {
273                                 t.Errorf("%s: error at %d:%d expected %d:%d", tt.Name, perr.Line, perr.Column, tt.Line, tt.Column)
274                         }
275                 } else if err != nil {
276                         t.Errorf("%s: unexpected error %v", tt.Name, err)
277                 } else if !reflect.DeepEqual(out, tt.Output) {
278                         t.Errorf("%s: out=%q want %q", tt.Name, out, tt.Output)
279                 }
280         }
281 }