w-data-csv 1.0.19 → 1.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/w-data-csv.umd.js +2 -2
- package/dist/w-data-csv.umd.js.map +1 -1
- package/docs/WDataCsv.mjs.html +124 -40
- package/docs/global.html +1174 -74
- package/docs/index.html +1 -1
- package/package.json +2 -2
- package/src/WDataCsv.mjs +123 -39
- package/test/readOpt.test.mjs +143 -0
package/docs/index.html
CHANGED
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
<br class="clear">
|
|
72
72
|
|
|
73
73
|
<footer>
|
|
74
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
74
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sat Aug 15 2026 17:02:41 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
75
75
|
</footer>
|
|
76
76
|
|
|
77
77
|
<script>prettyPrint();</script>
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "w-data-csv",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.21",
|
|
4
4
|
"main": "dist/w-data-csv.umd.js",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"csv-parser": "^3.2.1",
|
|
7
7
|
"strip-bom-stream": "^5.0.0",
|
|
8
|
-
"wsemi": "^1.8.
|
|
8
|
+
"wsemi": "^1.8.70"
|
|
9
9
|
},
|
|
10
10
|
"devDependencies": {
|
|
11
11
|
"w-package-tools": "^1.1.12"
|
package/src/WDataCsv.mjs
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { Readable } from 'stream'
|
|
1
|
+
import { Readable, Writable } from 'stream'
|
|
2
|
+
import { pipeline } from 'stream/promises'
|
|
2
3
|
import fs from 'fs'
|
|
3
4
|
import csvParse from 'csv-parser'
|
|
4
5
|
import stripBom from 'strip-bom-stream'
|
|
5
6
|
import get from 'lodash-es/get.js'
|
|
6
7
|
import fsIsFile from 'wsemi/src/fsIsFile.mjs'
|
|
8
|
+
import haskey from 'wsemi/src/haskey.mjs'
|
|
7
9
|
import isestr from 'wsemi/src/isestr.mjs'
|
|
8
10
|
import isstr from 'wsemi/src/isstr.mjs'
|
|
9
11
|
import isbol from 'wsemi/src/isbol.mjs'
|
|
@@ -13,11 +15,89 @@ import genPm from 'wsemi/src/genPm.mjs'
|
|
|
13
15
|
import ltdtkeysheads2mat from 'wsemi/src/ltdtkeysheads2mat.mjs'
|
|
14
16
|
|
|
15
17
|
|
|
18
|
+
//csv-parser可透傳之選項
|
|
19
|
+
//排除raw(其值回傳Buffer, 破壞ltdt與mat之字串契約)與outputByteOffset(其改變回傳形狀為{row,byteOffset})
|
|
20
|
+
let ksOptCsvParse = [
|
|
21
|
+
'headers', 'skipLines', 'skipComments', 'separator', 'quote',
|
|
22
|
+
'escape', 'newline', 'strict', 'mapHeaders', 'mapValues', 'maxRowBytes',
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
//genOptCsvParse, 自opt取出csv-parser可用選項, 未給者不傳入以維持csv-parser之預設
|
|
27
|
+
let genOptCsvParse = (opt) => {
|
|
28
|
+
|
|
29
|
+
//mode
|
|
30
|
+
let mode = get(opt, 'mode')
|
|
31
|
+
if (mode !== 'ltdt' && mode !== 'mat') {
|
|
32
|
+
mode = 'ltdt'
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//透傳
|
|
36
|
+
let o = {}
|
|
37
|
+
for (let k of ksOptCsvParse) {
|
|
38
|
+
if (haskey(opt, k)) {
|
|
39
|
+
o[k] = opt[k]
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//headers給true會使csv-parser之headers成為布林值, 各列鍵將全為_0,_1...之溢出鍵而成壞資料, 故一律視為未給
|
|
44
|
+
if (o.headers === true) {
|
|
45
|
+
delete o.headers
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
//mat模式固定關閉標頭, 否則第1列會被取為標頭
|
|
49
|
+
//且可避免headers給陣列時, 超出標頭數之欄位另生_N溢出鍵
|
|
50
|
+
if (mode === 'mat') {
|
|
51
|
+
o.headers = false
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return { mode, optCsvParse: o }
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
//getRows, 以pipeline串接各段stream, 使來源與中段stream之錯誤皆能被捕獲
|
|
59
|
+
let getRows = async (rs, opt) => {
|
|
60
|
+
|
|
61
|
+
let { mode, optCsvParse } = genOptCsvParse(opt)
|
|
62
|
+
|
|
63
|
+
let res = []
|
|
64
|
+
|
|
65
|
+
let ws = new Writable({
|
|
66
|
+
objectMode: true,
|
|
67
|
+
write(row, enc, cb) {
|
|
68
|
+
|
|
69
|
+
//mat模式時headers必為false, csv-parser依各列實際欄數自生0,1,2...之整數字串鍵,
|
|
70
|
+
//物件之整數字串鍵本就依數值升序排列, 故直接取值即為正確順序
|
|
71
|
+
res.push(mode === 'mat' ? Object.values(row) : row)
|
|
72
|
+
|
|
73
|
+
cb()
|
|
74
|
+
},
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
await pipeline(rs, stripBom(), csvParse(optCsvParse), ws)
|
|
78
|
+
|
|
79
|
+
return res
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
16
83
|
/**
|
|
17
84
|
* 解析CSV字串
|
|
18
85
|
*
|
|
19
|
-
* @param {String}
|
|
20
|
-
* @
|
|
86
|
+
* @param {String} inp 輸入CSV字串
|
|
87
|
+
* @param {Object} [opt={}] 輸入設定物件,預設{}
|
|
88
|
+
* @param {String} [opt.mode='ltdt'] 輸入回傳數據格式字串,可選ltdt(各數據列為物件)或mat(各數據列為陣列),預設ltdt
|
|
89
|
+
* @param {Boolean|Array} [opt.headers] 輸入標頭設定,給false代表無標頭列,給陣列代表無標頭列且以此陣列為欄名,不給則取第1列為標頭。因csv-parser於給true時會使各列成為_0,_1等溢出鍵之壞數據,故給true時視為不給。另mode為mat時本設定固定為false
|
|
90
|
+
* @param {Number} [opt.skipLines] 輸入解析前跳過列數整數。因csv-parser之註解列不計入行號,故與skipComments併用時計數基準會位移,兩者不建議同時使用
|
|
91
|
+
* @param {Boolean|String} [opt.skipComments] 輸入忽略註解列設定,給true代表跳過#開頭之列,給字串代表以該字元為註解符
|
|
92
|
+
* @param {String} [opt.separator] 輸入欄位分隔字元,因csv-parser僅取首個byte,故須為單字元
|
|
93
|
+
* @param {String} [opt.quote] 輸入引號字元,因csv-parser僅取首個byte,故須為單字元
|
|
94
|
+
* @param {String} [opt.escape] 輸入逃逸字元,因csv-parser僅取首個byte,故須為單字元
|
|
95
|
+
* @param {String} [opt.newline] 輸入行尾字元,因csv-parser僅取首個byte,故須為單字元
|
|
96
|
+
* @param {Boolean} [opt.strict] 輸入各列欄數是否須與標頭數相符布林值。因csv-parser於headers為false時會強制關閉本設定,故mode為mat時本設定無效
|
|
97
|
+
* @param {Function} [opt.mapHeaders] 輸入標頭轉換函式。因csv-parser僅於解析標頭列時呼叫,故mode為mat時不會被呼叫。另回傳null時該欄將被整欄丟棄
|
|
98
|
+
* @param {Function} [opt.mapValues] 輸入欄值轉換函式。mode為mat時其header參數恆為undefined
|
|
99
|
+
* @param {Number} [opt.maxRowBytes] 輸入單列位元組數上限整數
|
|
100
|
+
* @return {Promise} 回傳Promise,resolve回傳ltdt(各數據列為物件陣列)或mat(二維陣列),reject回傳錯誤訊息
|
|
21
101
|
* @example
|
|
22
102
|
*
|
|
23
103
|
* import wdc from './src/WDataCsv.mjs'
|
|
@@ -35,32 +115,28 @@ import ltdtkeysheads2mat from 'wsemi/src/ltdtkeysheads2mat.mjs'
|
|
|
35
115
|
* console.log(err)
|
|
36
116
|
* })
|
|
37
117
|
*
|
|
118
|
+
* await wdc.parseCsv(c, { mode: 'mat' })
|
|
119
|
+
* .then((mat) => {
|
|
120
|
+
* console.log(mat)
|
|
121
|
+
* // => [ [ 'NAME', 'AGE' ], [ 'Daffy Duck', '24' ], [ 'Bugs 邦妮', '22' ] ]
|
|
122
|
+
* })
|
|
123
|
+
* .catch((err) => {
|
|
124
|
+
* console.log(err)
|
|
125
|
+
* })
|
|
126
|
+
*
|
|
38
127
|
*/
|
|
39
|
-
async function parseCsv(inp) {
|
|
40
|
-
let res = []
|
|
41
|
-
|
|
42
|
-
let pm = genPm()
|
|
128
|
+
async function parseCsv(inp, opt = {}) {
|
|
43
129
|
|
|
44
130
|
//check
|
|
45
131
|
if (!isestr(inp)) {
|
|
46
132
|
return Promise.reject(`inp is not an effective string`)
|
|
47
133
|
}
|
|
48
134
|
|
|
49
|
-
Readable.from([inp])
|
|
50
|
-
.
|
|
51
|
-
.on('data', (chunk) => {
|
|
52
|
-
// console.log('data', chunk)
|
|
53
|
-
res.push(chunk)
|
|
54
|
-
})
|
|
55
|
-
.on('end', () => {
|
|
56
|
-
pm.resolve(res)
|
|
57
|
-
})
|
|
58
|
-
.on('error', (err) => {
|
|
135
|
+
return getRows(Readable.from([inp]), opt)
|
|
136
|
+
.catch((err) => {
|
|
59
137
|
console.log(err)
|
|
60
|
-
|
|
138
|
+
return Promise.reject(err)
|
|
61
139
|
})
|
|
62
|
-
|
|
63
|
-
return pm
|
|
64
140
|
}
|
|
65
141
|
|
|
66
142
|
|
|
@@ -68,7 +144,20 @@ async function parseCsv(inp) {
|
|
|
68
144
|
* 讀取CSV檔,自動清除BOM
|
|
69
145
|
*
|
|
70
146
|
* @param {String} fp 輸入檔案位置字串
|
|
71
|
-
* @
|
|
147
|
+
* @param {Object} [opt={}] 輸入設定物件,預設{}
|
|
148
|
+
* @param {String} [opt.mode='ltdt'] 輸入回傳數據格式字串,可選ltdt(各數據列為物件)或mat(各數據列為陣列),預設ltdt
|
|
149
|
+
* @param {Boolean|Array} [opt.headers] 輸入標頭設定,給false代表無標頭列,給陣列代表無標頭列且以此陣列為欄名,不給則取第1列為標頭。因csv-parser於給true時會使各列成為_0,_1等溢出鍵之壞數據,故給true時視為不給。另mode為mat時本設定固定為false
|
|
150
|
+
* @param {Number} [opt.skipLines] 輸入解析前跳過列數整數。因csv-parser之註解列不計入行號,故與skipComments併用時計數基準會位移,兩者不建議同時使用
|
|
151
|
+
* @param {Boolean|String} [opt.skipComments] 輸入忽略註解列設定,給true代表跳過#開頭之列,給字串代表以該字元為註解符
|
|
152
|
+
* @param {String} [opt.separator] 輸入欄位分隔字元,因csv-parser僅取首個byte,故須為單字元
|
|
153
|
+
* @param {String} [opt.quote] 輸入引號字元,因csv-parser僅取首個byte,故須為單字元
|
|
154
|
+
* @param {String} [opt.escape] 輸入逃逸字元,因csv-parser僅取首個byte,故須為單字元
|
|
155
|
+
* @param {String} [opt.newline] 輸入行尾字元,因csv-parser僅取首個byte,故須為單字元
|
|
156
|
+
* @param {Boolean} [opt.strict] 輸入各列欄數是否須與標頭數相符布林值。因csv-parser於headers為false時會強制關閉本設定,故mode為mat時本設定無效
|
|
157
|
+
* @param {Function} [opt.mapHeaders] 輸入標頭轉換函式。因csv-parser僅於解析標頭列時呼叫,故mode為mat時不會被呼叫。另回傳null時該欄將被整欄丟棄
|
|
158
|
+
* @param {Function} [opt.mapValues] 輸入欄值轉換函式。mode為mat時其header參數恆為undefined
|
|
159
|
+
* @param {Number} [opt.maxRowBytes] 輸入單列位元組數上限整數
|
|
160
|
+
* @return {Promise} 回傳Promise,resolve回傳ltdt(各數據列為物件陣列)或mat(二維陣列),reject回傳錯誤訊息
|
|
72
161
|
* @example
|
|
73
162
|
*
|
|
74
163
|
* import wdc from './src/WDataCsv.mjs'
|
|
@@ -84,33 +173,28 @@ async function parseCsv(inp) {
|
|
|
84
173
|
* console.log(err)
|
|
85
174
|
* })
|
|
86
175
|
*
|
|
176
|
+
* wdc.readCsv(fp, { mode: 'mat' })
|
|
177
|
+
* .then((mat) => {
|
|
178
|
+
* console.log(mat)
|
|
179
|
+
* // => [ [ 'NAME', 'AGE' ], [ 'Daffy Duck', '24' ], [ 'Bugs 邦妮', '22' ] ]
|
|
180
|
+
* })
|
|
181
|
+
* .catch((err) => {
|
|
182
|
+
* console.log(err)
|
|
183
|
+
* })
|
|
184
|
+
*
|
|
87
185
|
*/
|
|
88
|
-
async function readCsv(fp) {
|
|
89
|
-
let res = []
|
|
90
|
-
|
|
91
|
-
let pm = genPm()
|
|
186
|
+
async function readCsv(fp, opt = {}) {
|
|
92
187
|
|
|
93
188
|
//check
|
|
94
189
|
if (!fsIsFile(fp)) {
|
|
95
190
|
return Promise.reject(`fp[${fp}] is not exist`)
|
|
96
191
|
}
|
|
97
192
|
|
|
98
|
-
fs.createReadStream(fp)
|
|
99
|
-
.
|
|
100
|
-
.pipe(csvParse())
|
|
101
|
-
.on('data', (chunk) => {
|
|
102
|
-
// console.log('data', chunk)
|
|
103
|
-
res.push(chunk)
|
|
104
|
-
})
|
|
105
|
-
.on('end', () => {
|
|
106
|
-
pm.resolve(res)
|
|
107
|
-
})
|
|
108
|
-
.on('error', (err) => {
|
|
193
|
+
return getRows(fs.createReadStream(fp), opt)
|
|
194
|
+
.catch((err) => {
|
|
109
195
|
console.log(err)
|
|
110
|
-
|
|
196
|
+
return Promise.reject(err)
|
|
111
197
|
})
|
|
112
|
-
|
|
113
|
-
return pm
|
|
114
198
|
}
|
|
115
199
|
|
|
116
200
|
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import assert from 'assert'
|
|
3
|
+
import wdc from '../src/WDataCsv.mjs'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
//監測站原始CSV之結構: 前12列為儀器metadata, 第13列為#標記, 第14列為欄位名稱, 第15列起為量測數據
|
|
7
|
+
//另含短列, 空白列與長列, 用於驗證mat模式反映各列實際欄數
|
|
8
|
+
let csvSite = [
|
|
9
|
+
'1,v22.08.22,,,,,',
|
|
10
|
+
'2025ST1,,,,,,',
|
|
11
|
+
'1000,1000,,,,,',
|
|
12
|
+
'Chiayi,,,,,,',
|
|
13
|
+
'1,,,,,,',
|
|
14
|
+
'1,,,,,,',
|
|
15
|
+
'1,,,,,,',
|
|
16
|
+
'0.408,0,Piezo1,kg/cm2,,,',
|
|
17
|
+
'0.408,0,Piezo2,kg/cm2,,,',
|
|
18
|
+
'0.408,0,EXT,kg/cm2,,,',
|
|
19
|
+
'0.408,0,5V,kg/cm2,,,',
|
|
20
|
+
'x,,,,,,',
|
|
21
|
+
'#,,,,,,',
|
|
22
|
+
'X(gal),Y(gal),Z(gal),Piezo1,Piezo2,EXT,5V',
|
|
23
|
+
'0.214,0.143,-0.158,1.187,2.642,2.356,4.928',
|
|
24
|
+
'0.1,0.2,0.3',
|
|
25
|
+
'',
|
|
26
|
+
'"a,b",c,d,e,f,g,h,i',
|
|
27
|
+
].join('\r\n')
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
describe('readOpt', function() {
|
|
31
|
+
|
|
32
|
+
it('test opt undefined, 回歸至無opt之行為', async function() {
|
|
33
|
+
let rout = [{ NAME: 'Daffy Duck', AGE: '24' }, { NAME: 'Bugs 邦妮', AGE: '22' }]
|
|
34
|
+
|
|
35
|
+
let rRead = await wdc.readCsv('./g-test-in.csv')
|
|
36
|
+
assert.strict.deepEqual(rRead, rout)
|
|
37
|
+
|
|
38
|
+
let c = fs.readFileSync('./g-test-in.csv', 'utf8')
|
|
39
|
+
let rParse = await wdc.parseCsv(c)
|
|
40
|
+
assert.strict.deepEqual(rParse, rout)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('test mode mat with skipLines, 跳過儀器metadata後自欄位名稱列起回傳二維陣列', async function() {
|
|
44
|
+
let fp = './g-test-site.csv'
|
|
45
|
+
fs.writeFileSync(fp, csvSite, 'utf8')
|
|
46
|
+
|
|
47
|
+
let mat = await wdc.readCsv(fp, { mode: 'mat', skipLines: 13 })
|
|
48
|
+
|
|
49
|
+
//第1列為欄位名稱
|
|
50
|
+
assert.strict.deepEqual(mat[0], ['X(gal)', 'Y(gal)', 'Z(gal)', 'Piezo1', 'Piezo2', 'EXT', '5V'])
|
|
51
|
+
|
|
52
|
+
//第2列為7欄量測數據
|
|
53
|
+
assert.strict.deepEqual(mat[1], ['0.214', '0.143', '-0.158', '1.187', '2.642', '2.356', '4.928'])
|
|
54
|
+
|
|
55
|
+
//短列保留其實際欄數, 不補空
|
|
56
|
+
assert.strict.deepEqual(mat[2], ['0.1', '0.2', '0.3'])
|
|
57
|
+
|
|
58
|
+
//空白列為空陣列
|
|
59
|
+
assert.strict.deepEqual(mat[3], [])
|
|
60
|
+
|
|
61
|
+
//長列保留其實際欄數不截斷, 且引號內之逗號不被視為分隔字元
|
|
62
|
+
assert.strict.deepEqual(mat[4], ['a,b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
|
|
63
|
+
|
|
64
|
+
//各列皆為陣列, 無_N溢出鍵
|
|
65
|
+
assert.strict.deepEqual(mat.length, 5)
|
|
66
|
+
assert.strict.deepEqual(mat.every((v) => Array.isArray(v)), true)
|
|
67
|
+
|
|
68
|
+
fs.unlinkSync(fp)
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('test headers true, 視為未給而非產生_N溢出鍵之壞數據', async function() {
|
|
72
|
+
let r = await wdc.parseCsv('a,b\n1,2', { headers: true })
|
|
73
|
+
assert.strict.deepEqual(r, [{ a: '1', b: '2' }])
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('test mode mat with headers, headers固定為false故給陣列時不生_N溢出鍵', async function() {
|
|
77
|
+
let r = await wdc.parseCsv('1,2,3,4,5', { mode: 'mat', headers: ['h0', 'h1', 'h2'] })
|
|
78
|
+
assert.strict.deepEqual(r, [['1', '2', '3', '4', '5']])
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
it('test mode ltdt with headers, 給陣列代表無標頭列故第1列為數據', async function() {
|
|
82
|
+
let r = await wdc.parseCsv('a,b\n1,2', { headers: ['h0', 'h1'] })
|
|
83
|
+
assert.strict.deepEqual(r, [{ h0: 'a', h1: 'b' }, { h0: '1', h1: '2' }])
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('test raw and outputByteOffset, 不透傳以維持字串契約與回傳形狀', async function() {
|
|
87
|
+
let rRaw = await wdc.parseCsv('a,b\n1,2', { mode: 'mat', raw: true })
|
|
88
|
+
assert.strict.deepEqual(typeof rRaw[0][0], 'string')
|
|
89
|
+
|
|
90
|
+
let rOff = await wdc.parseCsv('a,b\n1,2', { mode: 'mat', outputByteOffset: true })
|
|
91
|
+
assert.strict.deepEqual(rOff[0], ['a', 'b'])
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it('test skipComments with skipLines, 註解列不計入行號故兩者併用時計數基準位移', async function() {
|
|
95
|
+
let c = 'm1,m2\nm3,m4\nm5,m6\n#,x\nA,B\n1,2'
|
|
96
|
+
|
|
97
|
+
let r1 = await wdc.parseCsv(c, { mode: 'mat', skipLines: 4 })
|
|
98
|
+
assert.strict.deepEqual(r1, [['A', 'B'], ['1', '2']])
|
|
99
|
+
|
|
100
|
+
let r2 = await wdc.parseCsv(c, { mode: 'mat', skipLines: 4, skipComments: true })
|
|
101
|
+
assert.strict.deepEqual(r2, [['1', '2']])
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
it('test bom, parseCsv與readCsv對含BOM內容之結果一致', async function() {
|
|
105
|
+
let c = 'NAME,AGE\r\nDaffy Duck,24\r\n'
|
|
106
|
+
let fp = './g-test-bom.csv'
|
|
107
|
+
fs.writeFileSync(fp, c, 'utf8')
|
|
108
|
+
|
|
109
|
+
let rParse = await wdc.parseCsv(c)
|
|
110
|
+
let rRead = await wdc.readCsv(fp)
|
|
111
|
+
|
|
112
|
+
assert.strict.deepEqual(rParse, rRead)
|
|
113
|
+
assert.strict.deepEqual(rParse, [{ NAME: 'Daffy Duck', AGE: '24' }])
|
|
114
|
+
|
|
115
|
+
fs.unlinkSync(fp)
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it('test error, stream錯誤轉為reject且不拋出未捕獲例外', async function() {
|
|
119
|
+
let err = null
|
|
120
|
+
await wdc.readCsv('./g-test-in.csv', { maxRowBytes: 1 })
|
|
121
|
+
.catch((e) => {
|
|
122
|
+
err = e
|
|
123
|
+
})
|
|
124
|
+
assert.strict.deepEqual(err !== null, true)
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
it('test reject payload, 檢核失敗時仍reject字串', async function() {
|
|
128
|
+
let e1 = null
|
|
129
|
+
await wdc.parseCsv('')
|
|
130
|
+
.catch((e) => {
|
|
131
|
+
e1 = e
|
|
132
|
+
})
|
|
133
|
+
assert.strict.deepEqual(e1, 'inp is not an effective string')
|
|
134
|
+
|
|
135
|
+
let e2 = null
|
|
136
|
+
await wdc.readCsv('./no-such-file.csv')
|
|
137
|
+
.catch((e) => {
|
|
138
|
+
e2 = e
|
|
139
|
+
})
|
|
140
|
+
assert.strict.deepEqual(e2, 'fp[./no-such-file.csv] is not exist')
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
})
|