v
Зеркало из https://github.com/vlang/v
1import encoding.csv
2
3fn test_encoding_csv_reader() {
4data := 'name,email,phone,other\njoe,joe@blow.com,0400000000,test\nsam,sam@likesham.com,0433000000,"test quoted field"\n#chris,chris@nomail.com,94444444,"commented row"\n'
5mut csv_reader := csv.new_reader(data)
6mut row_count := 0
7for {
8row := csv_reader.read() or { break }
9row_count++
10if row_count == 1 {
11assert row[0] == 'name'
12assert row[1] == 'email'
13assert row[2] == 'phone'
14assert row[3] == 'other'
15} else if row_count == 2 {
16assert row[0] == 'joe'
17assert row[1] == 'joe@blow.com'
18assert row[2] == '0400000000'
19assert row[3] == 'test'
20} else if row_count == 3 {
21assert row[0] == 'sam'
22assert row[1] == 'sam@likesham.com'
23assert row[2] == '0433000000'
24// quoted field
25assert row[3] == 'test quoted field'
26}
27}
28assert row_count == 3
29}
30
31fn test_encoding_csv_reader_with_custom_delimiter() {
32data := 'name|email|phone|other\njoe|joe@blow.com|0400000000|test\nsam|sam@likesham.com|0433000000|"test quoted field"\n#chris|chris@nomail.com|94444444|"commented row"\n'
33mut csv_reader := csv.new_reader(data, delimiter: `|`)
34mut row_count := 0
35for {
36row := csv_reader.read() or { break }
37row_count++
38if row_count == 1 {
39assert row[0] == 'name'
40assert row[1] == 'email'
41assert row[2] == 'phone'
42assert row[3] == 'other'
43} else if row_count == 2 {
44assert row[0] == 'joe'
45assert row[1] == 'joe@blow.com'
46assert row[2] == '0400000000'
47assert row[3] == 'test'
48} else if row_count == 3 {
49assert row[0] == 'sam'
50assert row[1] == 'sam@likesham.com'
51assert row[2] == '0433000000'
52// quoted field
53assert row[3] == 'test quoted field'
54}
55}
56assert row_count == 3
57}
58
59fn test_line_break_lf() {
60lf_data := 'name,email\njoe,joe@blow.com\n'
61mut csv_reader := csv.new_reader(lf_data)
62mut row_count := 0
63for {
64row := csv_reader.read() or { break }
65row_count++
66if row_count == 1 {
67assert row[0] == 'name'
68assert row[1] == 'email'
69} else if row_count == 2 {
70assert row[0] == 'joe'
71assert row[1] == 'joe@blow.com'
72}
73}
74assert row_count == 2
75}
76
77fn test_line_break_cr() {
78cr_data := 'name,email\rjoe,joe@blow.com\r'
79mut csv_reader := csv.new_reader(cr_data)
80mut row_count := 0
81for {
82row := csv_reader.read() or { break }
83row_count++
84if row_count == 1 {
85assert row[0] == 'name'
86assert row[1] == 'email'
87} else if row_count == 2 {
88assert row[0] == 'joe'
89assert row[1] == 'joe@blow.com'
90}
91}
92assert row_count == 2
93}
94
95fn test_line_break_crlf() {
96crlf_data := 'name,email\r\njoe,joe@blow.com\r\n'
97mut csv_reader := csv.new_reader(crlf_data)
98mut row_count := 0
99for {
100row := csv_reader.read() or { break }
101row_count++
102if row_count == 1 {
103assert row[0] == 'name'
104assert row[1] == 'email'
105} else if row_count == 2 {
106assert row[0] == 'joe'
107assert row[1] == 'joe@blow.com'
108}
109}
110assert row_count == 2
111}
112
113fn test_no_line_ending() {
114data := 'name,email,phone,other\njoe,joe@blow.com,0400000000,test'
115mut csv_reader := csv.new_reader(data)
116mut row_count := 0
117for {
118csv_reader.read() or { break }
119row_count++
120}
121assert row_count == 2
122}
123
124fn test_last_field_empty() {
125data := '"name","description","value"\n"one","first","1"\n"two","second",\n'
126mut csv_reader := csv.new_reader(data)
127mut row_count := 0
128for {
129row := csv_reader.read() or { break }
130row_count++
131if row_count == 1 {
132assert row[0] == 'name'
133assert row[1] == 'description'
134assert row[2] == 'value'
135} else if row_count == 2 {
136assert row[0] == 'one'
137assert row[1] == 'first'
138assert row[2] == '1'
139} else if row_count == 3 {
140assert row[0] == 'two'
141assert row[1] == 'second'
142assert row[2] == ''
143}
144}
145assert row_count == 3
146}
147
148fn test_empty_fields_no_quotes() {
149data := '1,2,3,4\n,6,7,8\n9,,11,12\n13,14,,16\n17,18,19,\n'
150
151mut csv_reader := csv.new_reader(data)
152mut row_count := 0
153for {
154row := csv_reader.read() or { break }
155row_count++
156if row_count == 1 {
157assert row[0] == '1'
158assert row[1] == '2'
159assert row[2] == '3'
160assert row[3] == '4'
161} else if row_count == 2 {
162assert row[0] == ''
163assert row[1] == '6'
164assert row[2] == '7'
165assert row[3] == '8'
166} else if row_count == 3 {
167assert row[0] == '9'
168assert row[1] == ''
169assert row[2] == '11'
170assert row[3] == '12'
171} else if row_count == 4 {
172assert row[0] == '13'
173assert row[1] == '14'
174assert row[2] == ''
175assert row[3] == '16'
176} else if row_count == 5 {
177assert row[0] == '17'
178assert row[1] == '18'
179assert row[2] == '19'
180assert row[3] == ''
181}
182}
183assert row_count == 5
184}
185
186fn test_empty_line() {
187data := '"name","description","value"\n\n\n"one","first","1"\n\n"two","second",\n'
188mut csv_reader := csv.new_reader(data)
189mut row_count := 0
190for {
191row := csv_reader.read() or { break }
192row_count++
193if row_count == 1 {
194assert row[0] == 'name'
195assert row[1] == 'description'
196assert row[2] == 'value'
197} else if row_count == 2 {
198assert row[0] == 'one'
199assert row[1] == 'first'
200assert row[2] == '1'
201} else if row_count == 3 {
202assert row[0] == 'two'
203assert row[1] == 'second'
204}
205}
206assert row_count == 3
207}
208
209fn test_field_multiple_line() {
210data := '"name","multiple
211
212line","value"\n"one","first","1"\n'
213mut csv_reader := csv.new_reader(data)
214mut row_count := 0
215for {
216row := csv_reader.read() or { break }
217row_count++
218if row_count == 1 {
219assert row[0] == 'name'
220assert row[1] == 'multiple\n\n line'
221assert row[2] == 'value'
222} else if row_count == 2 {
223assert row[0] == 'one'
224assert row[1] == 'first'
225assert row[2] == '1'
226}
227}
228assert row_count == 2
229}
230
231fn test_field_quotes_for_parts() {
232data := 'a1,"b1",c1\n"a2",b2,c2\na3,b3,"c3"\na4,b4,c4\n'
233mut csv_reader := csv.new_reader(data)
234mut row_count := 0
235for {
236row := csv_reader.read() or { break }
237row_count++
238if row_count == 1 {
239assert row[0] == 'a1'
240assert row[1] == 'b1'
241assert row[2] == 'c1'
242} else if row_count == 2 {
243assert row[0] == 'a2'
244assert row[1] == 'b2'
245assert row[2] == 'c2'
246} else if row_count == 3 {
247assert row[0] == 'a3'
248assert row[1] == 'b3'
249assert row[2] == 'c3'
250} else if row_count == 4 {
251assert row[0] == 'a4'
252assert row[1] == 'b4'
253assert row[2] == 'c4'
254}
255}
256assert row_count == 4
257}
258
259fn test_field_double_quotes() {
260row1 := '11,"12\n13"\n'
261row2 := '21,"2""2""\n23"\n'
262row3 := '"3""1""",32\n'
263data := row1 + row2 + row3
264mut csv_reader := csv.new_reader(data)
265mut row_count := 0
266for {
267row := csv_reader.read() or { break }
268row_count++
269if row_count == 1 {
270assert row[0] == '11'
271assert row[1] == '12\n13'
272} else if row_count == 2 {
273assert row[0] == '21'
274assert row[1] == '2"2"\n23'
275} else if row_count == 3 {
276assert row[0] == '3"1"'
277assert row[1] == '32'
278}
279}
280assert row_count == 3
281}
282
283struct Test {
284mut:
285id int
286bonus string
287amount int
288yes bool
289}
290
291fn test_decode_to_struct() {
292text := 'id,bonus,amount,yes\r\n1,bomb,1,true\r\n2,rocket,1,false,\r\n3,lightning,2,2\r\n'
293arr := csv.decode[Test](text)
294assert arr[0].id == 1
295assert arr[0].bonus == 'bomb'
296assert arr[0].amount == 1
297assert arr[0].yes == true
298assert arr[1].id == 2
299assert arr[1].bonus == 'rocket'
300assert arr[1].amount == 1
301assert arr[1].yes == false
302assert arr[2].id == 3
303assert arr[2].bonus == 'lightning'
304assert arr[2].amount == 2
305assert arr[2].yes == true
306assert arr.len == 3
307}
308