-
Notifications
You must be signed in to change notification settings - Fork 5
/
reader_test.ts
158 lines (131 loc) · 3.19 KB
/
reader_test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import { assertEquals, assertThrowsAsync } from "./dev_deps.ts";
import { readCSV, readCSVObjects } from "./reader.ts";
async function createReader(content: string): Promise<Deno.Reader> {
const buf = new Deno.Buffer();
const enc = new TextEncoder();
await buf.write(enc.encode(content));
return buf;
}
async function asyncArrayFrom<T>(
iter: AsyncIterableIterator<T>,
): Promise<Array<T>> {
const arr: T[] = [];
for await (const row of iter) {
arr.push(row);
}
return arr;
}
Deno.test({
name: "readCSVObjects parses simple file",
async fn() {
const reader = await createReader(`a,b,c
1,2,3`);
const rows = await asyncArrayFrom(readCSVObjects(reader));
assertEquals(rows, [{ a: "1", b: "2", c: "3" }]);
},
});
Deno.test({
name: "readCSV parses simple file",
async fn() {
const reader = await createReader(`1,2,3
a,b,c`);
const rows = await asyncArrayFrom(readCSV(reader));
assertEquals(rows, [
["1", "2", "3"],
["a", "b", "c"],
]);
},
});
Deno.test({
name: "readCSV skips empty lines",
async fn() {
const reader = await createReader(`1,2,3
a,b,c`);
const rows = await asyncArrayFrom(readCSV(reader));
assertEquals(rows, [
["1", "2", "3"],
["a", "b", "c"],
]);
},
});
Deno.test({
name: "readCSV parses emoji",
async fn() {
const reader = await createReader(`😀,2,3
a,😀,c`);
const rows = await asyncArrayFrom(readCSV(reader));
assertEquals(rows, [
["😀", "2", "3"],
["a", "😀", "c"],
]);
},
});
Deno.test({
name: "readCSV parses file with qoutes",
async fn() {
const reader = await createReader(`1,"2",3
a,"b
""1",c`);
const rows = await asyncArrayFrom(readCSV(reader));
assertEquals(rows, [
["1", "2", "3"],
["a", 'b\n"1', "c"],
]);
},
});
Deno.test({
name: "readCSV throws when qoute is unclosed",
async fn() {
const reader = await createReader(`1,"2`);
assertThrowsAsync(
async () => {
await asyncArrayFrom(readCSV(reader));
},
Error,
"Expected quote, received EOF",
);
},
});
Deno.test({
name: "readCSV throws when qoute is not last character in column",
async fn() {
const reader = await createReader(`1,"2"3`);
assertThrowsAsync(
async () => {
await asyncArrayFrom(readCSV(reader));
},
Error,
"Expected EOF, COLUMN_SEPARATOR, LINE_SEPARATOR; received 3",
);
},
});
Deno.test({
name: "readCSV parses huge file",
async fn() {
const stats = {
reads: 0,
inputBufferShrinks: 0,
columnBufferExpands: 0,
};
const reader = await createReader(
`aaaaaaaaaaaaaaaaaaaa,bbbbbbbbbbbbbbbbbbbbb\n11111111111111111111,22222222222222222222`,
);
const rows = await asyncArrayFrom(
readCSV(reader, {
_readerIteratorBufferSize: 1,
_columnBufferMinStepSize: 1,
_inputBufferIndexLimit: 1,
_stats: stats,
}),
);
assertEquals(rows, [
["aaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbb"],
["11111111111111111111", "22222222222222222222"],
]);
assertEquals(stats, {
reads: 85,
inputBufferShrinks: 84,
columnBufferExpands: 41,
});
},
});