w-orm-lmdb 1.0.17 → 1.0.18
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/README.md +15 -0
- package/dist/req-mingo.umd.js +1 -1
- package/dist/w-orm-lmdb.umd.js +2 -2
- package/dist/w-orm-lmdb.umd.js.map +1 -1
- package/docs/WOrmLmdb.html +23 -9
- package/docs/WOrmLmdb.mjs.html +109 -66
- package/docs/index.html +1 -1
- package/g-basic.mjs +15 -0
- package/package.json +1 -1
- package/src/WOrmLmdb.mjs +108 -65
- package/test/unit-event.test.mjs +242 -0
- package//350/263/207/346/226/231/345/272/253/345/207/275/346/225/270/345/233/236/345/202/263/345/256/232/347/276/251/350/250/210/347/256/227.md +130 -23
package/src/WOrmLmdb.mjs
CHANGED
|
@@ -23,6 +23,23 @@ import waitFun from 'wsemi/src/waitFun.mjs'
|
|
|
23
23
|
/**
|
|
24
24
|
* 操作資料庫(LMDB)
|
|
25
25
|
*
|
|
26
|
+
* 回傳物件為EventEmitter,除各操作函數外另發出change與error兩事件,供呼叫端於單一處集中觀察資料異動與失敗。
|
|
27
|
+
* 事件僅為附加通知,其所送出之資訊皆另有正規管道(操作結果經resolve、整批性錯誤經reject、逐筆失敗經該筆之err欄位),
|
|
28
|
+
* 故不監聽亦能取得完整資訊,且監聽與否不改變任何操作之回傳值。
|
|
29
|
+
*
|
|
30
|
+
* change事件,參數為(mode, data, res),於資料實際異動成功後發出:
|
|
31
|
+
* mode為操作別字串,可為'insert'、'save'、'del'、'delAll';save內若逐筆走自動插入則該筆另發出mode為'insert'之事件。
|
|
32
|
+
* data為本次操作之輸入數據,delAll固定為null。
|
|
33
|
+
* res為本次操作之回傳結果。
|
|
34
|
+
* 逐筆函數以整批為單位發出一次而不逐筆發出,select與selectByPk不發出本事件。
|
|
35
|
+
*
|
|
36
|
+
* error事件,參數為(mode, data, err),於操作發生錯誤時發出:
|
|
37
|
+
* mode為操作別字串,可為'select'、'selectByPk'、'insert'、'save'、'del'、'delAll'。
|
|
38
|
+
* data為本次操作之輸入數據,無輸入數據者為null。
|
|
39
|
+
* err為錯誤訊息字串,內容與正規管道所送出者一致。
|
|
40
|
+
* 整批性錯誤於reject之前發出;逐筆失敗於該筆結果定案後發出,每筆一次。
|
|
41
|
+
* 註: 逐筆失敗時整批仍resolve,故收到本事件不表示該次呼叫失敗;正常結果(如查無數據、主鍵未命中、全數已存在)不發出本事件。
|
|
42
|
+
*
|
|
26
43
|
* @class
|
|
27
44
|
* @param {Object} [opt={}] 輸入設定物件,預設{}
|
|
28
45
|
* @param {String} [opt.url='_db'] 輸入資料庫用資料夾字串,預設'_db'
|
|
@@ -118,7 +135,30 @@ function WOrmLmdb(opt = {}) {
|
|
|
118
135
|
})
|
|
119
136
|
}
|
|
120
137
|
|
|
121
|
-
//
|
|
138
|
+
//emitChange, 資料實際異動成功後發出, 事件僅為附加通知不承擔回傳義務
|
|
139
|
+
//一律包try/catch, 令訂閱函數自身拋錯不影響本次操作之結果
|
|
140
|
+
let emitChange = (mode, data, res) => {
|
|
141
|
+
try {
|
|
142
|
+
ee.emit('change', mode, data, res)
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
console.log(err)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
//emitError, 操作發生錯誤時發出, 錯誤訊息一律轉為字串
|
|
150
|
+
//此try/catch除攔訂閱函數之例外外另有必要: Node之EventEmitter於'error'無監聽者時會將錯誤直接拋出,
|
|
151
|
+
//若不攔則同一次操作會因呼叫端有無註冊監聽而走向不同結果
|
|
152
|
+
let emitError = (mode, data, err) => {
|
|
153
|
+
try {
|
|
154
|
+
ee.emit('error', mode, data, getErrMsg(err))
|
|
155
|
+
}
|
|
156
|
+
catch (errEmit) {
|
|
157
|
+
console.log(errEmit)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
//getErrMsg, 取錯誤訊息字串, 供逐筆結果之err欄位與error事件使用
|
|
122
162
|
let getErrMsg = (err) => {
|
|
123
163
|
let m = get(err, 'message')
|
|
124
164
|
if (isestr(m)) {
|
|
@@ -212,6 +252,10 @@ function WOrmLmdb(opt = {}) {
|
|
|
212
252
|
|
|
213
253
|
//check
|
|
214
254
|
if (isErr) {
|
|
255
|
+
|
|
256
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
257
|
+
emitError('select', null, res)
|
|
258
|
+
|
|
215
259
|
return Promise.reject(res)
|
|
216
260
|
}
|
|
217
261
|
|
|
@@ -261,6 +305,10 @@ function WOrmLmdb(opt = {}) {
|
|
|
261
305
|
|
|
262
306
|
//check
|
|
263
307
|
if (isErr) {
|
|
308
|
+
|
|
309
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
310
|
+
emitError('selectByPk', null, res)
|
|
311
|
+
|
|
264
312
|
return Promise.reject(res)
|
|
265
313
|
}
|
|
266
314
|
|
|
@@ -344,19 +392,15 @@ function WOrmLmdb(opt = {}) {
|
|
|
344
392
|
|
|
345
393
|
//emit, 於change可能須使用select, 故須放在重設快取之後
|
|
346
394
|
if (!isErr) {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
//emit
|
|
350
|
-
ee.emit('change', 'insert', data, res)
|
|
351
|
-
|
|
352
|
-
}
|
|
353
|
-
catch (err) {
|
|
354
|
-
console.log(err)
|
|
355
|
-
}
|
|
395
|
+
emitChange('insert', data, res)
|
|
356
396
|
}
|
|
357
397
|
|
|
358
398
|
//check
|
|
359
399
|
if (isErr) {
|
|
400
|
+
|
|
401
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
402
|
+
emitError('insert', data, res)
|
|
403
|
+
|
|
360
404
|
return Promise.reject(res)
|
|
361
405
|
}
|
|
362
406
|
|
|
@@ -525,16 +569,15 @@ function WOrmLmdb(opt = {}) {
|
|
|
525
569
|
//update, 不能保證插入多少, 一律重設快取
|
|
526
570
|
_cache = null
|
|
527
571
|
|
|
528
|
-
|
|
572
|
+
//emit
|
|
573
|
+
emitChange('insert', [v], rest)
|
|
529
574
|
|
|
530
|
-
|
|
531
|
-
ee.emit('change', 'insert', [v], rest)
|
|
532
|
-
|
|
533
|
-
}
|
|
534
|
-
catch (err) {
|
|
535
|
-
console.log(err)
|
|
536
|
-
}
|
|
575
|
+
}
|
|
537
576
|
|
|
577
|
+
//emit, 逐筆失敗於該筆結果定案後發出, 每筆一次
|
|
578
|
+
//此事件之發出不表示整批失敗, 整批仍resolve, 該筆以ok為0回報
|
|
579
|
+
if (rest.ok === 0) {
|
|
580
|
+
emitError('save', [v], rest.err)
|
|
538
581
|
}
|
|
539
582
|
|
|
540
583
|
return rest
|
|
@@ -550,20 +593,17 @@ function WOrmLmdb(opt = {}) {
|
|
|
550
593
|
_cache = null
|
|
551
594
|
|
|
552
595
|
//emit, 於change可能須使用select, 故須放在重設快取之後
|
|
596
|
+
//逐筆失敗之error事件已於各筆定案時發出, 故必早於本整批change
|
|
553
597
|
if (!isErr) {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
//emit
|
|
557
|
-
ee.emit('change', 'save', data, res)
|
|
558
|
-
|
|
559
|
-
}
|
|
560
|
-
catch (err) {
|
|
561
|
-
console.log(err)
|
|
562
|
-
}
|
|
598
|
+
emitChange('save', data, res)
|
|
563
599
|
}
|
|
564
600
|
|
|
565
601
|
//check
|
|
566
602
|
if (isErr) {
|
|
603
|
+
|
|
604
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
605
|
+
emitError('save', data, res)
|
|
606
|
+
|
|
567
607
|
return Promise.reject(res)
|
|
568
608
|
}
|
|
569
609
|
|
|
@@ -612,38 +652,42 @@ function WOrmLmdb(opt = {}) {
|
|
|
612
652
|
if (!isestr(id)) {
|
|
613
653
|
//未給有效v.id視為該筆數據有問題而無法處理, 以ok為0並附err回報,
|
|
614
654
|
//與[已給v.id但查無數據]之ok為1有別, 二者須可由ok分辨
|
|
615
|
-
return
|
|
655
|
+
//註: 此處不可直接return, 否則會跳過本回調末尾之error事件發出
|
|
656
|
+
rest = {
|
|
616
657
|
n: 0,
|
|
617
658
|
nDeleted: 0,
|
|
618
659
|
ok: 0,
|
|
619
660
|
err: `can not delete by invalid id[${id}]`,
|
|
620
661
|
}
|
|
621
662
|
}
|
|
663
|
+
else {
|
|
622
664
|
|
|
623
|
-
|
|
624
|
-
|
|
665
|
+
//查找資料表內v.id
|
|
666
|
+
let vv = await getValue(id) //不會有catch
|
|
625
667
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
668
|
+
//check
|
|
669
|
+
if (iseobj(vv)) {
|
|
670
|
+
//已存在v.id則須刪除
|
|
629
671
|
|
|
630
|
-
|
|
631
|
-
|
|
672
|
+
//del
|
|
673
|
+
await client.del(id)
|
|
674
|
+
|
|
675
|
+
//rest
|
|
676
|
+
rest = {
|
|
677
|
+
n: 1,
|
|
678
|
+
nDeleted: 1,
|
|
679
|
+
ok: 1,
|
|
680
|
+
}
|
|
632
681
|
|
|
633
|
-
//rest
|
|
634
|
-
rest = {
|
|
635
|
-
n: 1,
|
|
636
|
-
nDeleted: 1,
|
|
637
|
-
ok: 1,
|
|
638
682
|
}
|
|
683
|
+
else {
|
|
684
|
+
//不存在v.id則不刪除, 未命中故n為0
|
|
685
|
+
rest = {
|
|
686
|
+
n: 0,
|
|
687
|
+
nDeleted: 0,
|
|
688
|
+
ok: 1,
|
|
689
|
+
}
|
|
639
690
|
|
|
640
|
-
}
|
|
641
|
-
else {
|
|
642
|
-
//不存在v.id則不刪除, 未命中故n為0
|
|
643
|
-
rest = {
|
|
644
|
-
n: 0,
|
|
645
|
-
nDeleted: 0,
|
|
646
|
-
ok: 1,
|
|
647
691
|
}
|
|
648
692
|
|
|
649
693
|
}
|
|
@@ -661,6 +705,12 @@ function WOrmLmdb(opt = {}) {
|
|
|
661
705
|
|
|
662
706
|
}
|
|
663
707
|
|
|
708
|
+
//emit, 逐筆失敗於該筆結果定案後發出, 每筆一次
|
|
709
|
+
//此事件之發出不表示整批失敗, 整批仍resolve, 該筆以ok為0回報
|
|
710
|
+
if (rest.ok === 0) {
|
|
711
|
+
emitError('del', [v], rest.err)
|
|
712
|
+
}
|
|
713
|
+
|
|
664
714
|
return rest
|
|
665
715
|
})
|
|
666
716
|
|
|
@@ -674,20 +724,17 @@ function WOrmLmdb(opt = {}) {
|
|
|
674
724
|
_cache = null
|
|
675
725
|
|
|
676
726
|
//emit, 於change可能須使用select, 故須放在重設快取之後
|
|
727
|
+
//逐筆失敗之error事件已於各筆定案時發出, 故必早於本整批change
|
|
677
728
|
if (!isErr) {
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
//emit
|
|
681
|
-
ee.emit('change', 'del', data, res)
|
|
682
|
-
|
|
683
|
-
}
|
|
684
|
-
catch (err) {
|
|
685
|
-
console.log(err)
|
|
686
|
-
}
|
|
729
|
+
emitChange('del', data, res)
|
|
687
730
|
}
|
|
688
731
|
|
|
689
732
|
//check
|
|
690
733
|
if (isErr) {
|
|
734
|
+
|
|
735
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
736
|
+
emitError('del', data, res)
|
|
737
|
+
|
|
691
738
|
return Promise.reject(res)
|
|
692
739
|
}
|
|
693
740
|
|
|
@@ -789,19 +836,15 @@ function WOrmLmdb(opt = {}) {
|
|
|
789
836
|
|
|
790
837
|
//emit, 於change可能須使用select, 故須放在重設快取之後
|
|
791
838
|
if (!isErr) {
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
//emit
|
|
795
|
-
ee.emit('change', 'delAll', null, res)
|
|
796
|
-
|
|
797
|
-
}
|
|
798
|
-
catch (err) {
|
|
799
|
-
console.log(err)
|
|
800
|
-
}
|
|
839
|
+
emitChange('delAll', null, res)
|
|
801
840
|
}
|
|
802
841
|
|
|
803
842
|
//check
|
|
804
843
|
if (isErr) {
|
|
844
|
+
|
|
845
|
+
//emit, 整批性錯誤須於reject之前發出
|
|
846
|
+
emitError('delAll', null, res)
|
|
847
|
+
|
|
805
848
|
return Promise.reject(res)
|
|
806
849
|
}
|
|
807
850
|
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import assert from 'assert'
|
|
2
|
+
import _ from 'lodash-es'
|
|
3
|
+
import w from 'wsemi'
|
|
4
|
+
import WOrm from '../src/WOrmLmdb.mjs'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
describe('event', function() {
|
|
8
|
+
let rt = null
|
|
9
|
+
let vans = {}
|
|
10
|
+
let vget = {}
|
|
11
|
+
|
|
12
|
+
before(async function() {
|
|
13
|
+
|
|
14
|
+
w.fsDeleteFolder('./_db_event')
|
|
15
|
+
|
|
16
|
+
let url = './_db_event'
|
|
17
|
+
|
|
18
|
+
//evs, 蒐集事件, 事件名與各參數皆記錄以供比對
|
|
19
|
+
let mkEvs = function(wo) {
|
|
20
|
+
let evs = []
|
|
21
|
+
wo.on('change', function(mode, data, res) {
|
|
22
|
+
evs.push({ ev: 'change', mode, res })
|
|
23
|
+
})
|
|
24
|
+
wo.on('error', function(mode, data, err) {
|
|
25
|
+
evs.push({ ev: 'error', mode, data, err })
|
|
26
|
+
})
|
|
27
|
+
return evs
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
//change事件之形狀: 逐筆函數以整批為單位發出一次
|
|
31
|
+
let woC = WOrm({ url, db: 'worm', cl: 'ch' })
|
|
32
|
+
let evsC = mkEvs(woC)
|
|
33
|
+
await woC.insert([{ id: 'c1' }, { id: 'c2' }])
|
|
34
|
+
await woC.save({ id: 'c1', a: 1 })
|
|
35
|
+
await woC.del({ id: 'c2' })
|
|
36
|
+
await woC.delAll()
|
|
37
|
+
vget[1] = _.map(evsC, function(v) {
|
|
38
|
+
return `${v.ev}:${v.mode}`
|
|
39
|
+
})
|
|
40
|
+
await woC.close()
|
|
41
|
+
|
|
42
|
+
//save之逐筆插入另發mode為insert之事件, 且早於整批save事件
|
|
43
|
+
let woI = WOrm({ url, db: 'worm', cl: 'ins' })
|
|
44
|
+
let evsI = mkEvs(woI)
|
|
45
|
+
await woI.save({ id: 'i1', a: 1 })
|
|
46
|
+
vget[2] = _.map(evsI, function(v) {
|
|
47
|
+
return `${v.ev}:${v.mode}`
|
|
48
|
+
})
|
|
49
|
+
await woI.close()
|
|
50
|
+
|
|
51
|
+
//error事件: 整批性錯誤, 須於reject之前發出且err為字串
|
|
52
|
+
let woE = WOrm({ url, db: 'worm', cl: 'errb', autoGenPk: false })
|
|
53
|
+
let evsE = mkEvs(woE)
|
|
54
|
+
rt = null
|
|
55
|
+
await woE.insert({ name: 'no-id' })
|
|
56
|
+
.then(function() {
|
|
57
|
+
rt = 'resolve'
|
|
58
|
+
})
|
|
59
|
+
.catch(function() {
|
|
60
|
+
rt = 'reject'
|
|
61
|
+
})
|
|
62
|
+
vget[3] = rt
|
|
63
|
+
vget[4] = _.map(evsE, function(v) {
|
|
64
|
+
return `${v.ev}:${v.mode}`
|
|
65
|
+
})
|
|
66
|
+
vget[5] = w.isestr(_.get(evsE, '0.err'))
|
|
67
|
+
vget[6] = _.get(evsE, '0.data') !== null
|
|
68
|
+
await woE.close()
|
|
69
|
+
|
|
70
|
+
//error事件: 逐筆失敗, 整批仍resolve且每筆一次
|
|
71
|
+
let woD = WOrm({ url, db: 'worm', cl: 'errp' })
|
|
72
|
+
let evsD = mkEvs(woD)
|
|
73
|
+
await woD.insert({ id: 'd1' })
|
|
74
|
+
evsD.length = 0
|
|
75
|
+
rt = null
|
|
76
|
+
await woD.del([{ id: 'd1' }, { name: 'no-id-a' }, { name: 'no-id-b' }])
|
|
77
|
+
.then(function(msg) {
|
|
78
|
+
rt = _.map(msg, 'ok')
|
|
79
|
+
})
|
|
80
|
+
.catch(function() {
|
|
81
|
+
rt = 'reject'
|
|
82
|
+
})
|
|
83
|
+
vget[7] = rt
|
|
84
|
+
vget[8] = _.map(evsD, function(v) {
|
|
85
|
+
return `${v.ev}:${v.mode}`
|
|
86
|
+
})
|
|
87
|
+
vget[9] = w.isestr(_.get(evsD, '0.err'))
|
|
88
|
+
await woD.close()
|
|
89
|
+
|
|
90
|
+
//正常結果不得發出error事件
|
|
91
|
+
let woN = WOrm({ url, db: 'worm', cl: 'norm' })
|
|
92
|
+
let evsN = mkEvs(woN)
|
|
93
|
+
await woN.insert({ id: 'n1', a: 1 })
|
|
94
|
+
evsN.length = 0
|
|
95
|
+
await woN.insert({ id: 'n1', a: 2 }) //已存在, nInserted為0
|
|
96
|
+
await woN.save({ id: 'n1', a: 1 }) //合併後內容相同, 不寫入
|
|
97
|
+
await woN.save({ id: 'n2' }, { autoInsert: false }) //不存在且不autoInsert
|
|
98
|
+
await woN.del({ id: 'n-none' }) //主鍵未命中
|
|
99
|
+
await woN.delAll({ zz: 'none' }) //條件無命中
|
|
100
|
+
await woN.selectByPk('n-none') //查無數據
|
|
101
|
+
vget[10] = _.size(_.filter(evsN, function(v) {
|
|
102
|
+
return v.ev === 'error'
|
|
103
|
+
}))
|
|
104
|
+
await woN.close()
|
|
105
|
+
|
|
106
|
+
//核心不變式: 同一操作於有註冊與未註冊error監聽兩種情況下, 回傳值須完全相同
|
|
107
|
+
let run = async function(withListener) {
|
|
108
|
+
let wo = WOrm({ url, db: 'worm', cl: `inv${withListener ? 1 : 0}`, autoGenPk: false })
|
|
109
|
+
if (withListener) {
|
|
110
|
+
wo.on('error', function() {})
|
|
111
|
+
}
|
|
112
|
+
let r = {}
|
|
113
|
+
|
|
114
|
+
//整批性錯誤
|
|
115
|
+
r.batch = await wo.insert({ name: 'no-id' })
|
|
116
|
+
.then(function(msg) {
|
|
117
|
+
return { type: 'resolve', msg }
|
|
118
|
+
})
|
|
119
|
+
.catch(function() {
|
|
120
|
+
return { type: 'reject' }
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
//逐筆失敗
|
|
124
|
+
await wo.insert({ id: 'x1' })
|
|
125
|
+
r.each = await wo.del([{ id: 'x1' }, { name: 'no-id' }])
|
|
126
|
+
.then(function(msg) {
|
|
127
|
+
return {
|
|
128
|
+
type: 'resolve',
|
|
129
|
+
msg: _.map(msg, function(v) {
|
|
130
|
+
return _.omit(v, 'err')
|
|
131
|
+
}),
|
|
132
|
+
}
|
|
133
|
+
})
|
|
134
|
+
.catch(function() {
|
|
135
|
+
return { type: 'reject' }
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
await wo.close()
|
|
139
|
+
return r
|
|
140
|
+
}
|
|
141
|
+
let rWith = await run(true)
|
|
142
|
+
let rWithout = await run(false)
|
|
143
|
+
vget[11] = _.isEqual(rWith, rWithout)
|
|
144
|
+
vget[12] = rWithout.batch.type
|
|
145
|
+
vget[13] = rWithout.each.type
|
|
146
|
+
|
|
147
|
+
//訂閱函數拋錯不得影響本次操作
|
|
148
|
+
let woT = WOrm({ url, db: 'worm', cl: 'thr' })
|
|
149
|
+
woT.on('change', function() {
|
|
150
|
+
throw new Error('listener boom')
|
|
151
|
+
})
|
|
152
|
+
woT.on('error', function() {
|
|
153
|
+
throw new Error('listener boom')
|
|
154
|
+
})
|
|
155
|
+
rt = null
|
|
156
|
+
await woT.insert({ id: 't1', a: 1 })
|
|
157
|
+
.then(function(msg) {
|
|
158
|
+
rt = msg
|
|
159
|
+
})
|
|
160
|
+
.catch(function(msg) {
|
|
161
|
+
rt = 'reject: ' + msg.toString()
|
|
162
|
+
})
|
|
163
|
+
vget[14] = rt
|
|
164
|
+
await woT.close()
|
|
165
|
+
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
//逐筆函數以整批為單位發出一次change, 不逐筆發出
|
|
169
|
+
vans[1] = ['change:insert', 'change:save', 'change:del', 'change:delAll']
|
|
170
|
+
it(`should get ${JSON.stringify(vans[1])} for change events`, async function() {
|
|
171
|
+
assert.strict.deepStrictEqual(vget[1], vans[1])
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
vans[2] = ['change:insert', 'change:save']
|
|
175
|
+
it(`should get ${JSON.stringify(vans[2])} for change events of save with autoInsert`, async function() {
|
|
176
|
+
assert.strict.deepStrictEqual(vget[2], vans[2])
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
vans[3] = 'reject'
|
|
180
|
+
it(`should get ${JSON.stringify(vans[3])} for insert without id by autoGenPk=false`, async function() {
|
|
181
|
+
assert.strict.deepStrictEqual(vget[3], vans[3])
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
vans[4] = ['error:insert']
|
|
185
|
+
it(`should get ${JSON.stringify(vans[4])} for error event of batch error`, async function() {
|
|
186
|
+
assert.strict.deepStrictEqual(vget[4], vans[4])
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
vans[5] = true
|
|
190
|
+
it(`should get ${JSON.stringify(vans[5])} for err of error event being string`, async function() {
|
|
191
|
+
assert.strict.deepStrictEqual(vget[5], vans[5])
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
vans[6] = true
|
|
195
|
+
it(`should get ${JSON.stringify(vans[6])} for data of error event being input data`, async function() {
|
|
196
|
+
assert.strict.deepStrictEqual(vget[6], vans[6])
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
//逐筆失敗時整批仍resolve, 且每筆失敗各發出一次error
|
|
200
|
+
vans[7] = [1, 0, 0]
|
|
201
|
+
it(`should get ${JSON.stringify(vans[7])} for ok of each item when items failed`, async function() {
|
|
202
|
+
assert.strict.deepStrictEqual(vget[7], vans[7])
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
vans[8] = ['error:del', 'error:del', 'change:del']
|
|
206
|
+
it(`should get ${JSON.stringify(vans[8])} for error events emitted before change`, async function() {
|
|
207
|
+
assert.strict.deepStrictEqual(vget[8], vans[8])
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
vans[9] = true
|
|
211
|
+
it(`should get ${JSON.stringify(vans[9])} for err of each error event being string`, async function() {
|
|
212
|
+
assert.strict.deepStrictEqual(vget[9], vans[9])
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
//正常結果不得發出error
|
|
216
|
+
vans[10] = 0
|
|
217
|
+
it(`should get ${JSON.stringify(vans[10])} for error events by normal results`, async function() {
|
|
218
|
+
assert.strict.deepStrictEqual(vget[10], vans[10])
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
//T10.1核心不變式
|
|
222
|
+
vans[11] = true
|
|
223
|
+
it(`should get ${JSON.stringify(vans[11])} for same results with and without error listener`, async function() {
|
|
224
|
+
assert.strict.deepStrictEqual(vget[11], vans[11])
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
vans[12] = 'reject'
|
|
228
|
+
it(`should get ${JSON.stringify(vans[12])} for batch error still rejecting without error listener`, async function() {
|
|
229
|
+
assert.strict.deepStrictEqual(vget[12], vans[12])
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
vans[13] = 'resolve'
|
|
233
|
+
it(`should get ${JSON.stringify(vans[13])} for each-item failure still resolving without error listener`, async function() {
|
|
234
|
+
assert.strict.deepStrictEqual(vget[13], vans[13])
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
vans[14] = { n: 1, nInserted: 1, ok: 1 }
|
|
238
|
+
it(`should get ${JSON.stringify(vans[14])} for result not affected by throwing listener`, async function() {
|
|
239
|
+
assert.strict.deepStrictEqual(vget[14], vans[14])
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
})
|