w-orm-mongodb 1.1.42 → 1.1.44

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.
@@ -599,6 +599,392 @@ describe('insert', function() {
599
599
  })
600
600
 
601
601
 
602
+ describe('insert returnList', function() {
603
+ let vans = {}
604
+ let vget = {}
605
+
606
+ before(async function() {
607
+ this.timeout(120000)
608
+
609
+ let cl = 'inslist'
610
+ let wo = WOrm(genOpt(cl))
611
+ await wo.delAll()
612
+
613
+ //預設不給option時之形狀須為單一聚合物件
614
+ vget[1] = await wo.insert([{ id: 'r1' }, { id: 'r2' }])
615
+
616
+ //明確給false時形狀同預設
617
+ vget[2] = await wo.insert({ id: 'r3' }, { returnList: false })
618
+
619
+ //開啟後須回與輸入等長且保序之陣列, 全新者nInserted皆為1
620
+ vget[3] = await wo.insert([{ id: 'r4' }, { id: 'r5' }, { id: 'r6' }], { returnList: true })
621
+
622
+ //對位正確: 中間那筆已存在, 僅該位置之nInserted為0
623
+ vget[4] = await wo.insert([
624
+ { id: 'r7' },
625
+ { id: 'r5' }, //已存在
626
+ { id: 'r8' },
627
+ ], { returnList: true })
628
+
629
+ //同批含重複主鍵, 僅首筆之nInserted為1
630
+ vget[5] = await wo.insert([
631
+ { id: 'r9' },
632
+ { id: 'r9' },
633
+ { id: 'r9' },
634
+ ], { returnList: true })
635
+
636
+ //不變式: filter計數須等於聚合模式之nInserted
637
+ await wo.delAll()
638
+ let rsIn = [
639
+ { id: 's1' },
640
+ { id: 's2' },
641
+ { id: 's3' },
642
+ { id: 's4' },
643
+ ]
644
+ await wo.insert([{ id: 's2' }, { id: 's4' }]) //先寫入其中2筆
645
+ let rl = await wo.insert(rsIn, { returnList: true })
646
+ await wo.delAll()
647
+ await wo.insert([{ id: 's2' }, { id: 's4' }])
648
+ let rg = await wo.insert(rsIn)
649
+ vget[6] = rl.filter((v) => v.nInserted === 1).length
650
+ vget[7] = rg.nInserted
651
+ vget[8] = vget[6] === vget[7]
652
+
653
+ //逐筆元素之鍵集合須恰為n,nInserted,ok
654
+ vget[9] = rl.map(genKeys)
655
+
656
+ //輸入無效時開啟者回空陣列, 未開啟者回聚合物件
657
+ vget[10] = await wo.insert(null, { returnList: true })
658
+ vget[11] = await wo.insert(null)
659
+
660
+ //單一物件輸入亦須回長度為1之陣列
661
+ await wo.delAll()
662
+ vget[12] = await wo.insert({ id: 't1' }, { returnList: true })
663
+
664
+ //全數已存在時, 各元素之nInserted皆為0且不得reject
665
+ vget[13] = await wo.insert({ id: 't1' }, { returnList: true })
666
+
667
+ //change事件之res即本次實際回傳值
668
+ let woEv = WOrm(genOpt('inslistev'))
669
+ await woEv.delAll()
670
+ let resEv = null
671
+ woEv.on('change', function(mode, data, res) {
672
+ resEv = res
673
+ })
674
+ let rEv = await woEv.insert([{ id: 'v1' }, { id: 'v2' }], { returnList: true })
675
+ vget[14] = JSON.stringify(resEv) === JSON.stringify(rEv)
676
+
677
+ //autoGenPk為false且未帶id者仍為整批reject, 不因returnList而降為逐筆
678
+ let woOff = WOrm(genOptPk('inslistpkoff', false))
679
+ await woOff.delAll()
680
+ let rtOff = null
681
+ await woOff.insert([{ id: 'w1' }, { name: 'no-id' }], { returnList: true })
682
+ .then(function(msg) {
683
+ rtOff = `不應resolve: ${JSON.stringify(msg)}`
684
+ })
685
+ .catch(function(msg) {
686
+ rtOff = msg.toString()
687
+ })
688
+ vget[15] = rtOff
689
+ vget[16] = await woOff.selectByPk('w1')
690
+
691
+ })
692
+
693
+ vans[1] = { n: 2, nInserted: 2, ok: 1 }
694
+ it(`should get ${JSON.stringify(vans[1])} for insert without option`, async function() {
695
+ assert.strict.deepStrictEqual(vget[1], vans[1])
696
+ })
697
+
698
+ vans[2] = { n: 1, nInserted: 1, ok: 1 }
699
+ it(`should get ${JSON.stringify(vans[2])} for insert with returnList=false`, async function() {
700
+ assert.strict.deepStrictEqual(vget[2], vans[2])
701
+ })
702
+
703
+ vans[3] = [
704
+ { n: 1, nInserted: 1, ok: 1 },
705
+ { n: 1, nInserted: 1, ok: 1 },
706
+ { n: 1, nInserted: 1, ok: 1 }
707
+ ]
708
+ it(`should get ${JSON.stringify(vans[3])} for insert with returnList=true`, async function() {
709
+ assert.strict.deepStrictEqual(vget[3], vans[3])
710
+ })
711
+
712
+ vans[4] = [
713
+ { n: 1, nInserted: 1, ok: 1 },
714
+ { n: 1, nInserted: 0, ok: 1 },
715
+ { n: 1, nInserted: 1, ok: 1 }
716
+ ]
717
+ it(`should get ${JSON.stringify(vans[4])} for keeping order and position in returnList`, async function() {
718
+ assert.strict.deepStrictEqual(vget[4], vans[4])
719
+ })
720
+
721
+ vans[5] = [
722
+ { n: 1, nInserted: 1, ok: 1 },
723
+ { n: 1, nInserted: 0, ok: 1 },
724
+ { n: 1, nInserted: 0, ok: 1 }
725
+ ]
726
+ it(`should get ${JSON.stringify(vans[5])} for only first one inserted by duplicated id in same batch`, async function() {
727
+ assert.strict.deepStrictEqual(vget[5], vans[5])
728
+ })
729
+
730
+ vans[6] = 2
731
+ it(`should get ${JSON.stringify(vans[6])} for count of nInserted===1 in returnList`, async function() {
732
+ assert.strict.deepStrictEqual(vget[6], vans[6])
733
+ })
734
+
735
+ vans[7] = 2
736
+ it(`should get ${JSON.stringify(vans[7])} for nInserted in aggregated mode`, async function() {
737
+ assert.strict.deepStrictEqual(vget[7], vans[7])
738
+ })
739
+
740
+ vans[8] = true
741
+ it(`should get ${JSON.stringify(vans[8])} for same count between returnList and aggregated mode`, async function() {
742
+ assert.strict.deepStrictEqual(vget[8], vans[8])
743
+ })
744
+
745
+ vans[9] = ['n,nInserted,ok', 'n,nInserted,ok', 'n,nInserted,ok', 'n,nInserted,ok']
746
+ it(`should get ${JSON.stringify(vans[9])} for key set of returnList element`, async function() {
747
+ assert.strict.deepStrictEqual(vget[9], vans[9])
748
+ })
749
+
750
+ vans[10] = []
751
+ it(`should get ${JSON.stringify(vans[10])} for invalid data with returnList=true`, async function() {
752
+ assert.strict.deepStrictEqual(vget[10], vans[10])
753
+ })
754
+
755
+ vans[11] = { n: 0, nInserted: 0, ok: 1 }
756
+ it(`should get ${JSON.stringify(vans[11])} for invalid data with returnList=false`, async function() {
757
+ assert.strict.deepStrictEqual(vget[11], vans[11])
758
+ })
759
+
760
+ vans[12] = [{ n: 1, nInserted: 1, ok: 1 }]
761
+ it(`should get ${JSON.stringify(vans[12])} for single object with returnList=true`, async function() {
762
+ assert.strict.deepStrictEqual(vget[12], vans[12])
763
+ })
764
+
765
+ vans[13] = [{ n: 1, nInserted: 0, ok: 1 }]
766
+ it(`should get ${JSON.stringify(vans[13])} for all existed with returnList=true`, async function() {
767
+ assert.strict.deepStrictEqual(vget[13], vans[13])
768
+ })
769
+
770
+ vans[14] = true
771
+ it(`should get ${JSON.stringify(vans[14])} for res of change event being actual return value`, async function() {
772
+ assert.strict.deepStrictEqual(vget[14], vans[14])
773
+ })
774
+
775
+ vans[15] = 'Error: invalid data[1].id, autoGenPk is false'
776
+ it(`should get ${JSON.stringify(vans[15])} for autoGenPk=false with returnList=true`, async function() {
777
+ assert.strict.deepStrictEqual(vget[15], vans[15])
778
+ })
779
+
780
+ vans[16] = null
781
+ it(`should get ${JSON.stringify(vans[16])} for not writing valid records in rejected returnList batch`, async function() {
782
+ assert.strict.deepStrictEqual(vget[16], vans[16])
783
+ })
784
+
785
+ })
786
+
787
+
788
+ //insertBulk之語義與insert不同: insert跳過已存在者而整批ok為1, insertBulk則整批reject且不寫入任何一筆
789
+ //本檔之容器為standalone, 無交易可用, 故走補償動作路徑; 交易路徑另見api-insertbulk-rs.test.mjs
790
+
791
+
792
+ describe('insertBulk', function() {
793
+ let rt = null
794
+ let vans = {}
795
+ let vget = {}
796
+
797
+ before(async function() {
798
+ this.timeout(120000)
799
+
800
+ let cl = 'bulkcnt'
801
+ let wo = WOrm(genOpt(cl))
802
+ await wo.delAll()
803
+
804
+ //全新3筆, nInserted須等於n
805
+ vget[1] = await wo.insertBulk([
806
+ { id: 'b1', name: 'peter' },
807
+ { id: 'b2', name: 'rosemary' },
808
+ { id: 'b3', name: 'kettle' },
809
+ ])
810
+ vget[2] = (await wo.select()).length
811
+
812
+ //撞既有主鍵須整批reject
813
+ rt = null
814
+ let nBefore = (await wo.select()).length
815
+ await wo.insertBulk([
816
+ { id: 'b4', name: 'new1' },
817
+ { id: 'b2', name: 'dup' },
818
+ { id: 'b5', name: 'new2' },
819
+ ])
820
+ .then(function(msg) {
821
+ rt = `不應resolve: ${JSON.stringify(msg)}`
822
+ })
823
+ .catch(function(msg) {
824
+ rt = msg.toString()
825
+ })
826
+ vget[3] = rt.indexOf('E11000') >= 0 || rt.indexOf('duplicate key') >= 0
827
+
828
+ //失敗後資料表不得有任何新增
829
+ vget[4] = (await wo.select()).length - nBefore
830
+ vget[5] = [
831
+ await wo.selectByPk('b4'),
832
+ await wo.selectByPk('b5'),
833
+ ]
834
+
835
+ //撞既有主鍵者本身不得被改動
836
+ vget[6] = (await wo.selectByPk('b2')).name
837
+
838
+ //同批含重複主鍵須整批reject
839
+ rt = null
840
+ nBefore = (await wo.select()).length
841
+ await wo.insertBulk([
842
+ { id: 'b6', name: 'a' },
843
+ { id: 'b6', name: 'b' },
844
+ { id: 'b7', name: 'c' },
845
+ ])
846
+ .then(function(msg) {
847
+ rt = `不應resolve: ${JSON.stringify(msg)}`
848
+ })
849
+ .catch(function(msg) {
850
+ rt = msg.toString()
851
+ })
852
+ vget[7] = rt.indexOf('E11000') >= 0 || rt.indexOf('duplicate key') >= 0
853
+ vget[8] = (await wo.select()).length - nBefore
854
+ vget[9] = [
855
+ await wo.selectByPk('b6'),
856
+ await wo.selectByPk('b7'),
857
+ ]
858
+
859
+ //單一物件輸入亦須可用
860
+ vget[10] = await wo.insertBulk({ id: 'b8', name: 'single' })
861
+
862
+ //輸入無效視為空結果
863
+ vget[11] = await wo.insertBulk(null)
864
+
865
+ //鍵集合須與insert完全相同
866
+ let ri = await wo.insert({ id: 'b9', name: 'x' })
867
+ vget[12] = [genKeys(vget[1]), genKeys(vget[10]), genKeys(vget[11]), genKeys(ri)]
868
+
869
+ //autoGenPk預設為true, 未帶id者自動產生
870
+ vget[13] = await wo.insertBulk([{ name: 'nopk1' }, { name: 'nopk2' }])
871
+
872
+ //autoGenPk為false且未帶id者須reject, 且同批之有效筆數不得被寫入
873
+ let woOff = WOrm(genOptPk('bulkpkoff', false))
874
+ await woOff.delAll()
875
+ rt = null
876
+ await woOff.insertBulk([
877
+ { id: 'p-ok1', name: 'ok1' },
878
+ { name: 'no-id' },
879
+ ])
880
+ .then(function(msg) {
881
+ rt = `不應resolve: ${JSON.stringify(msg)}`
882
+ })
883
+ .catch(function(msg) {
884
+ rt = msg.toString()
885
+ })
886
+ vget[14] = rt
887
+ vget[15] = await woOff.selectByPk('p-ok1')
888
+
889
+ //事件, 成功時發change, 失敗時發error且mode為insertBulk
890
+ let woEv = WOrm(genOpt('bulkevent'))
891
+ await woEv.delAll()
892
+ let evs = []
893
+ woEv.on('change', function(mode) {
894
+ evs.push(`change:${mode}`)
895
+ })
896
+ woEv.on('error', function(mode) {
897
+ evs.push(`error:${mode}`)
898
+ })
899
+ await woEv.insertBulk({ id: 'e1', name: 'a' })
900
+ await woEv.insertBulk({ id: 'e1', name: 'b' }).catch(() => {})
901
+ vget[16] = evs
902
+
903
+ })
904
+
905
+ vans[1] = { n: 3, nInserted: 3, ok: 1 }
906
+ it(`should get ${JSON.stringify(vans[1])} for insertBulk 3 new records`, async function() {
907
+ assert.strict.deepStrictEqual(vget[1], vans[1])
908
+ })
909
+
910
+ vans[2] = 3
911
+ it(`should get ${JSON.stringify(vans[2])} for records after insertBulk`, async function() {
912
+ assert.strict.deepStrictEqual(vget[2], vans[2])
913
+ })
914
+
915
+ vans[3] = true
916
+ it(`should get ${JSON.stringify(vans[3])} for reject of insertBulk with existed id`, async function() {
917
+ assert.strict.deepStrictEqual(vget[3], vans[3])
918
+ })
919
+
920
+ vans[4] = 0
921
+ it(`should get ${JSON.stringify(vans[4])} for no record added after rejected insertBulk`, async function() {
922
+ assert.strict.deepStrictEqual(vget[4], vans[4])
923
+ })
924
+
925
+ vans[5] = [null, null]
926
+ it(`should get ${JSON.stringify(vans[5])} for not writing any record in rejected insertBulk`, async function() {
927
+ assert.strict.deepStrictEqual(vget[5], vans[5])
928
+ })
929
+
930
+ vans[6] = 'rosemary'
931
+ it(`should get ${JSON.stringify(vans[6])} for not modifying existed record by rejected insertBulk`, async function() {
932
+ assert.strict.deepStrictEqual(vget[6], vans[6])
933
+ })
934
+
935
+ vans[7] = true
936
+ it(`should get ${JSON.stringify(vans[7])} for reject of insertBulk with duplicated id in same batch`, async function() {
937
+ assert.strict.deepStrictEqual(vget[7], vans[7])
938
+ })
939
+
940
+ vans[8] = 0
941
+ it(`should get ${JSON.stringify(vans[8])} for no record added after insertBulk with duplicated id`, async function() {
942
+ assert.strict.deepStrictEqual(vget[8], vans[8])
943
+ })
944
+
945
+ vans[9] = [null, null]
946
+ it(`should get ${JSON.stringify(vans[9])} for not writing any record by duplicated id in same batch`, async function() {
947
+ assert.strict.deepStrictEqual(vget[9], vans[9])
948
+ })
949
+
950
+ vans[10] = { n: 1, nInserted: 1, ok: 1 }
951
+ it(`should get ${JSON.stringify(vans[10])} for insertBulk with single object`, async function() {
952
+ assert.strict.deepStrictEqual(vget[10], vans[10])
953
+ })
954
+
955
+ vans[11] = { n: 0, nInserted: 0, ok: 1 }
956
+ it(`should get ${JSON.stringify(vans[11])} for insertBulk with invalid data`, async function() {
957
+ assert.strict.deepStrictEqual(vget[11], vans[11])
958
+ })
959
+
960
+ vans[12] = ['n,nInserted,ok', 'n,nInserted,ok', 'n,nInserted,ok', 'n,nInserted,ok']
961
+ it(`should get ${JSON.stringify(vans[12])} for same key set between insertBulk and insert`, async function() {
962
+ assert.strict.deepStrictEqual(vget[12], vans[12])
963
+ })
964
+
965
+ vans[13] = { n: 2, nInserted: 2, ok: 1 }
966
+ it(`should get ${JSON.stringify(vans[13])} for insertBulk without id by default autoGenPk`, async function() {
967
+ assert.strict.deepStrictEqual(vget[13], vans[13])
968
+ })
969
+
970
+ vans[14] = 'Error: invalid data[1].id, autoGenPk is false'
971
+ it(`should get ${JSON.stringify(vans[14])} for insertBulk without id by autoGenPk=false`, async function() {
972
+ assert.strict.deepStrictEqual(vget[14], vans[14])
973
+ })
974
+
975
+ vans[15] = null
976
+ it(`should get ${JSON.stringify(vans[15])} for not writing valid records in rejected insertBulk by autoGenPk`, async function() {
977
+ assert.strict.deepStrictEqual(vget[15], vans[15])
978
+ })
979
+
980
+ vans[16] = ['change:insertBulk', 'error:insertBulk']
981
+ it(`should get ${JSON.stringify(vans[16])} for events of insertBulk`, async function() {
982
+ assert.strict.deepStrictEqual(vget[16], vans[16])
983
+ })
984
+
985
+ })
986
+
987
+
602
988
  describe('save', function() {
603
989
  let vans = {}
604
990
  let vget = {}
@@ -0,0 +1,290 @@
1
+ import assert from 'assert'
2
+ import mongodb from 'mongodb'
3
+ import WOrm from '../src/WOrmMongodb.mjs'
4
+ import { genUrlRs, startContainerRs, stopContainer } from './lib/api-setup.mjs'
5
+
6
+
7
+ //insertBulk之全有全無有兩條實作路徑, 依部署而異:
8
+ //具replica set或分片叢集者以交易包覆, standalone無交易可用而以補償動作達成
9
+ //本檔專測交易路徑, 故另起replica set容器; 補償路徑見api-basic.test.mjs之insertBulk
10
+
11
+
12
+ let ctName = 'worm-test-mongodb-rs'
13
+ let ctDb = 'worm'
14
+ let ctPort = null //容器對外埠, 由startContainerRs動態取得
15
+
16
+
17
+ //genOpt
18
+ let genOpt = (cl) => {
19
+ return {
20
+ url: genUrlRs(ctPort),
21
+ db: ctDb,
22
+ cl,
23
+ }
24
+ }
25
+
26
+ //genKeys
27
+ let genKeys = (v) => {
28
+ return Object.keys(v).sort().join(',')
29
+ }
30
+
31
+ //getHello, 直接由驅動取拓樸資訊, 用於確認本容器確為replica set
32
+ let getHello = async () => {
33
+ let client = new mongodb.MongoClient(genUrlRs(ctPort))
34
+ let hello = null
35
+ try {
36
+ hello = await client.db(ctDb).admin().command({ hello: 1 })
37
+ }
38
+ finally {
39
+ await client.close()
40
+ }
41
+ return hello
42
+ }
43
+
44
+
45
+ before(async function() {
46
+ this.timeout(600000) //含拉取映像、服務啟動與選舉
47
+ ctPort = await startContainerRs(ctName)
48
+ })
49
+
50
+ after(async function() {
51
+ this.timeout(120000)
52
+ await stopContainer(ctName)
53
+ })
54
+
55
+
56
+ describe('insertBulk by transaction', function() {
57
+ let rt = null
58
+ let vans = {}
59
+ let vget = {}
60
+
61
+ before(async function() {
62
+ this.timeout(300000)
63
+
64
+ //確認本容器確為replica set, 否則以下即非在測交易路徑
65
+ //套件內判定交易可用與否之依據即為hello之setName與msg, 故此處成立即表示套件必走交易路徑
66
+ let hello = await getHello()
67
+ vget[1] = {
68
+ isRs: typeof hello.setName === 'string' && hello.setName.length > 0,
69
+ isWritablePrimary: hello.isWritablePrimary === true,
70
+ }
71
+
72
+ let cl = 'bulktx'
73
+ let wo = WOrm(genOpt(cl))
74
+ await wo.delAll()
75
+
76
+ //全新3筆, nInserted須等於n
77
+ vget[2] = await wo.insertBulk([
78
+ { id: 't1', name: 'peter' },
79
+ { id: 't2', name: 'rosemary' },
80
+ { id: 't3', name: 'kettle' },
81
+ ])
82
+ vget[3] = (await wo.select()).length
83
+
84
+ //撞既有主鍵須整批reject且回滾
85
+ rt = null
86
+ let nBefore = (await wo.select()).length
87
+ await wo.insertBulk([
88
+ { id: 't4', name: 'new1' },
89
+ { id: 't2', name: 'dup' },
90
+ { id: 't5', name: 'new2' },
91
+ ])
92
+ .then(function(msg) {
93
+ rt = `不應resolve: ${JSON.stringify(msg)}`
94
+ })
95
+ .catch(function(msg) {
96
+ rt = msg.toString()
97
+ })
98
+ vget[4] = rt.indexOf('E11000') >= 0 || rt.indexOf('duplicate key') >= 0
99
+
100
+ //回滾後資料表不得有任何新增
101
+ vget[5] = (await wo.select()).length - nBefore
102
+ vget[6] = [
103
+ await wo.selectByPk('t4'),
104
+ await wo.selectByPk('t5'),
105
+ ]
106
+
107
+ //撞既有主鍵者本身不得被改動
108
+ vget[7] = (await wo.selectByPk('t2')).name
109
+
110
+ //同批含重複主鍵須整批reject且回滾
111
+ rt = null
112
+ nBefore = (await wo.select()).length
113
+ await wo.insertBulk([
114
+ { id: 't6', name: 'a' },
115
+ { id: 't6', name: 'b' },
116
+ { id: 't7', name: 'c' },
117
+ ])
118
+ .then(function(msg) {
119
+ rt = `不應resolve: ${JSON.stringify(msg)}`
120
+ })
121
+ .catch(function(msg) {
122
+ rt = msg.toString()
123
+ })
124
+ vget[8] = rt.indexOf('E11000') >= 0 || rt.indexOf('duplicate key') >= 0
125
+ vget[9] = (await wo.select()).length - nBefore
126
+ vget[10] = [
127
+ await wo.selectByPk('t6'),
128
+ await wo.selectByPk('t7'),
129
+ ]
130
+
131
+ //較大批次亦須全有全無, 用於驗證分批送出時之回滾
132
+ rt = null
133
+ await wo.delAll()
134
+ let rs = Array.from({ length: 200 }, (v, k) => {
135
+ return { id: `m${k}`, name: `n${k}` }
136
+ })
137
+ vget[11] = await wo.insertBulk(rs)
138
+ vget[12] = (await wo.select()).length
139
+
140
+ //末筆撞既有主鍵, 前199筆皆不得殘留
141
+ rt = null
142
+ await wo.delAll()
143
+ await wo.insert({ id: 'm199', name: 'pre' })
144
+ nBefore = (await wo.select()).length
145
+ await wo.insertBulk(rs)
146
+ .then(function(msg) {
147
+ rt = `不應resolve: ${JSON.stringify(msg)}`
148
+ })
149
+ .catch(function(msg) {
150
+ rt = msg.toString()
151
+ })
152
+ vget[13] = rt.indexOf('E11000') >= 0 || rt.indexOf('duplicate key') >= 0
153
+ vget[14] = (await wo.select()).length - nBefore
154
+
155
+ //輸入無效與單一物件
156
+ let woS = WOrm(genOpt('bulktxmisc'))
157
+ await woS.delAll()
158
+ vget[15] = await woS.insertBulk(null)
159
+ vget[16] = await woS.insertBulk({ id: 's1', name: 'single' })
160
+ vget[17] = [genKeys(vget[15]), genKeys(vget[16])]
161
+
162
+ //事件
163
+ let woEv = WOrm(genOpt('bulktxevent'))
164
+ await woEv.delAll()
165
+ let evs = []
166
+ woEv.on('change', function(mode) {
167
+ evs.push(`change:${mode}`)
168
+ })
169
+ woEv.on('error', function(mode) {
170
+ evs.push(`error:${mode}`)
171
+ })
172
+ await woEv.insertBulk({ id: 'e1', name: 'a' })
173
+ await woEv.insertBulk({ id: 'e1', name: 'b' }).catch(() => {})
174
+ vget[18] = evs
175
+
176
+ //其餘函數於replica set下行為須與standalone相同
177
+ let woO = WOrm(genOpt('bulktxother'))
178
+ await woO.delAll()
179
+ vget[19] = await woO.insert([{ id: 'o1' }, { id: 'o1' }, { id: 'o2' }])
180
+ vget[20] = await woO.save({ id: 'o1', name: 'x' })
181
+ vget[21] = await woO.del({ id: 'o2' })
182
+
183
+ })
184
+
185
+ vans[1] = { isRs: true, isWritablePrimary: true }
186
+ it(`should get ${JSON.stringify(vans[1])} for topology being replica set`, async function() {
187
+ assert.strict.deepStrictEqual(vget[1], vans[1])
188
+ })
189
+
190
+ vans[2] = { n: 3, nInserted: 3, ok: 1 }
191
+ it(`should get ${JSON.stringify(vans[2])} for insertBulk 3 new records`, async function() {
192
+ assert.strict.deepStrictEqual(vget[2], vans[2])
193
+ })
194
+
195
+ vans[3] = 3
196
+ it(`should get ${JSON.stringify(vans[3])} for records after insertBulk`, async function() {
197
+ assert.strict.deepStrictEqual(vget[3], vans[3])
198
+ })
199
+
200
+ vans[4] = true
201
+ it(`should get ${JSON.stringify(vans[4])} for reject of insertBulk with existed id`, async function() {
202
+ assert.strict.deepStrictEqual(vget[4], vans[4])
203
+ })
204
+
205
+ vans[5] = 0
206
+ it(`should get ${JSON.stringify(vans[5])} for rollback after rejected insertBulk`, async function() {
207
+ assert.strict.deepStrictEqual(vget[5], vans[5])
208
+ })
209
+
210
+ vans[6] = [null, null]
211
+ it(`should get ${JSON.stringify(vans[6])} for not writing any record in rejected insertBulk`, async function() {
212
+ assert.strict.deepStrictEqual(vget[6], vans[6])
213
+ })
214
+
215
+ vans[7] = 'rosemary'
216
+ it(`should get ${JSON.stringify(vans[7])} for not modifying existed record by rejected insertBulk`, async function() {
217
+ assert.strict.deepStrictEqual(vget[7], vans[7])
218
+ })
219
+
220
+ vans[8] = true
221
+ it(`should get ${JSON.stringify(vans[8])} for reject of insertBulk with duplicated id in same batch`, async function() {
222
+ assert.strict.deepStrictEqual(vget[8], vans[8])
223
+ })
224
+
225
+ vans[9] = 0
226
+ it(`should get ${JSON.stringify(vans[9])} for rollback after insertBulk with duplicated id`, async function() {
227
+ assert.strict.deepStrictEqual(vget[9], vans[9])
228
+ })
229
+
230
+ vans[10] = [null, null]
231
+ it(`should get ${JSON.stringify(vans[10])} for not writing any record by duplicated id in same batch`, async function() {
232
+ assert.strict.deepStrictEqual(vget[10], vans[10])
233
+ })
234
+
235
+ vans[11] = { n: 200, nInserted: 200, ok: 1 }
236
+ it(`should get ${JSON.stringify(vans[11])} for insertBulk 200 records`, async function() {
237
+ assert.strict.deepStrictEqual(vget[11], vans[11])
238
+ })
239
+
240
+ vans[12] = 200
241
+ it(`should get ${JSON.stringify(vans[12])} for records after insertBulk 200 records`, async function() {
242
+ assert.strict.deepStrictEqual(vget[12], vans[12])
243
+ })
244
+
245
+ vans[13] = true
246
+ it(`should get ${JSON.stringify(vans[13])} for reject of insertBulk 200 records with last one conflicted`, async function() {
247
+ assert.strict.deepStrictEqual(vget[13], vans[13])
248
+ })
249
+
250
+ vans[14] = 0
251
+ it(`should get ${JSON.stringify(vans[14])} for rollback of 200 records batch`, async function() {
252
+ assert.strict.deepStrictEqual(vget[14], vans[14])
253
+ })
254
+
255
+ vans[15] = { n: 0, nInserted: 0, ok: 1 }
256
+ it(`should get ${JSON.stringify(vans[15])} for insertBulk with invalid data`, async function() {
257
+ assert.strict.deepStrictEqual(vget[15], vans[15])
258
+ })
259
+
260
+ vans[16] = { n: 1, nInserted: 1, ok: 1 }
261
+ it(`should get ${JSON.stringify(vans[16])} for insertBulk with single object`, async function() {
262
+ assert.strict.deepStrictEqual(vget[16], vans[16])
263
+ })
264
+
265
+ vans[17] = ['n,nInserted,ok', 'n,nInserted,ok']
266
+ it(`should get ${JSON.stringify(vans[17])} for fixed key set of insertBulk`, async function() {
267
+ assert.strict.deepStrictEqual(vget[17], vans[17])
268
+ })
269
+
270
+ vans[18] = ['change:insertBulk', 'error:insertBulk']
271
+ it(`should get ${JSON.stringify(vans[18])} for events of insertBulk`, async function() {
272
+ assert.strict.deepStrictEqual(vget[18], vans[18])
273
+ })
274
+
275
+ vans[19] = { n: 3, nInserted: 2, ok: 1 }
276
+ it(`should get ${JSON.stringify(vans[19])} for insert on replica set`, async function() {
277
+ assert.strict.deepStrictEqual(vget[19], vans[19])
278
+ })
279
+
280
+ vans[20] = [{ n: 1, nInserted: 0, nModified: 1, ok: 1 }]
281
+ it(`should get ${JSON.stringify(vans[20])} for save on replica set`, async function() {
282
+ assert.strict.deepStrictEqual(vget[20], vans[20])
283
+ })
284
+
285
+ vans[21] = [{ n: 1, nDeleted: 1, ok: 1 }]
286
+ it(`should get ${JSON.stringify(vans[21])} for del on replica set`, async function() {
287
+ assert.strict.deepStrictEqual(vget[21], vans[21])
288
+ })
289
+
290
+ })