w-serv-orm 1.1.8 → 1.1.10
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 +1 -6
- package/dist/w-serv-orm.umd.js +2 -2
- package/dist/w-serv-orm.umd.js.map +1 -1
- package/docs/WServOrm.html +10 -158
- package/docs/WServOrm.mjs.html +14 -15
- package/docs/index.html +1 -1
- package/g-mOrm.mjs +1 -6
- package/package.json +1 -1
- package/src/WServOrm.mjs +13 -14
- package/src/checkOptRemoved.mjs +25 -0
- package/src/getProc.mjs +106 -189
- package/test/api-procOrm.test.mjs +1 -1
- package/test/unit-WServOrm.test.mjs +145 -89
- package/test/unit-mapOrm.test.mjs +3 -3
- package/src/getItemsFail.mjs +0 -5
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import assert from 'assert'
|
|
2
2
|
import WServOrm from '../src/WServOrm.mjs'
|
|
3
3
|
import getMapOrm from '../src/getMapOrm.mjs'
|
|
4
|
-
import
|
|
4
|
+
import getProc from '../src/getProc.mjs'
|
|
5
|
+
import checkOptRemoved from '../src/checkOptRemoved.mjs'
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
//替身ORM工廠: 以name辨識所屬實例, 呼叫紀錄寫入log; 回傳形狀依w-orm系列規格(save、del回逐筆陣列, insert回聚合物件)
|
|
@@ -29,7 +30,6 @@ function mkWOrm(name, log, behavior = {}) {
|
|
|
29
30
|
|
|
30
31
|
let dsAll = { tests: { keys: ['id', 'name', 'isActive', 'timeUpdate'] } }
|
|
31
32
|
let dsNoTime = { tests: { keys: ['id', 'name', 'isActive'] } }
|
|
32
|
-
let optOff = { useCheckUser: false, useExcludeWhenNotAdmin: false }
|
|
33
33
|
let wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
|
|
34
34
|
|
|
35
35
|
async function getReject(pm) {
|
|
@@ -63,8 +63,8 @@ describe('WServOrm實例互不干擾', function() {
|
|
|
63
63
|
it('I01 兩實例之procOrm各自路由至自己的ORM', async function() {
|
|
64
64
|
//R1: 雙向皆打自己的ORM, 解構後呼叫亦然
|
|
65
65
|
let log = []
|
|
66
|
-
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a'
|
|
67
|
-
let B = WServOrm(dsAll, mkWOrm('B', log), 'url-b', 'db-b'
|
|
66
|
+
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a')
|
|
67
|
+
let B = WServOrm(dsAll, mkWOrm('B', log), 'url-b', 'db-b')
|
|
68
68
|
let { procOrm: pA } = A
|
|
69
69
|
let { procOrm: pB } = B
|
|
70
70
|
await pA('u1', 'tests', 'select', {})
|
|
@@ -77,8 +77,8 @@ describe('WServOrm實例互不干擾', function() {
|
|
|
77
77
|
it('I02 各實例依自己之ds調整數據', async function() {
|
|
78
78
|
//R1: A之ds含timeUpdate而補值, B之ds不含而不補
|
|
79
79
|
let log = []
|
|
80
|
-
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a'
|
|
81
|
-
let B = WServOrm(dsNoTime, mkWOrm('B', log), 'url-b', 'db-b'
|
|
80
|
+
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a')
|
|
81
|
+
let B = WServOrm(dsNoTime, mkWOrm('B', log), 'url-b', 'db-b')
|
|
82
82
|
await A.procOrm('u1', 'tests', 'save', [{ id: 'x' }])
|
|
83
83
|
await B.procOrm('u1', 'tests', 'save', [{ id: 'y' }])
|
|
84
84
|
assert.strict.deepEqual(log.map((v) => v.name), ['A', 'B'])
|
|
@@ -86,45 +86,52 @@ describe('WServOrm實例互不干擾', function() {
|
|
|
86
86
|
assert.ok(!('timeUpdate' in log[1].data[0]))
|
|
87
87
|
})
|
|
88
88
|
|
|
89
|
-
it('I03
|
|
90
|
-
//
|
|
89
|
+
it('I03 已移除之設定給予非預設值即建構拋錯且不建立ORM', async function() {
|
|
90
|
+
//R3: useCheckUser、getUserById、useExcludeWhenNotAdmin已移除; 給予未給、null、false以外之值即拋錯, 避免使用端以為仍有檢查而無聲失去
|
|
91
|
+
//拋錯於建立各資料表ORM之前, 否則已開啟之ORM(如lmdb之檔案)無從關閉; 亦不影響既有實例
|
|
91
92
|
let log = []
|
|
92
|
-
let
|
|
93
|
-
let
|
|
94
|
-
let
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
93
|
+
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a')
|
|
94
|
+
let created = 0
|
|
95
|
+
let WOrmCount = function() {
|
|
96
|
+
created++
|
|
97
|
+
return {}
|
|
98
|
+
}
|
|
99
|
+
let bads = [
|
|
100
|
+
['useCheckUser', true],
|
|
101
|
+
['useCheckUser', 'true'],
|
|
102
|
+
['useCheckUser', 1],
|
|
103
|
+
['getUserById', async () => ({ isActive: 'y' })],
|
|
104
|
+
['getUserById', 'x'],
|
|
105
|
+
['useExcludeWhenNotAdmin', true],
|
|
106
|
+
['useExcludeWhenNotAdmin', 'n'],
|
|
107
|
+
]
|
|
108
|
+
for (let [k, v] of bads) {
|
|
109
|
+
assert.throws(() => WServOrm(dsAll, WOrmCount, 'url-x', 'db-x', { [k]: v }), (e) => e instanceof Error && e.message.startsWith(`opt.${k} has been removed, `), `${k}: ${String(v)}`)
|
|
110
|
+
}
|
|
111
|
+
assert.strict.equal(created, 0)
|
|
112
|
+
let r = await A.procOrm('u1', 'tests', 'select', {})
|
|
113
|
+
assert.strict.deepEqual(r.map((v) => v.id), ['A-r1', 'A-r2'])
|
|
109
114
|
})
|
|
110
115
|
|
|
111
|
-
it('I04
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
let
|
|
115
|
-
let
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
116
|
+
it('I04 已移除之設定未給、null或false照常建構, 不檢查使用者亦不過濾', async function() {
|
|
117
|
+
//R3: 四個使用端現行之設定({useCheckUser:false, getUserById:null, useExcludeWhenNotAdmin:false})升版照常可用
|
|
118
|
+
//procOrm不做授權: userId不檢查(含空字串、null、undefined), select不依使用者濾除isActive為n者
|
|
119
|
+
let opts = [undefined, null, {}, { useCheckUser: null }, { useCheckUser: false, getUserById: null, useExcludeWhenNotAdmin: false }]
|
|
120
|
+
for (let opt of opts) {
|
|
121
|
+
let X = WServOrm(dsAll, mkWOrm('X', []), 'url-x', 'db-x', opt)
|
|
122
|
+
for (let userId of ['u1', '', null, undefined]) {
|
|
123
|
+
let r = await X.procOrm(userId, 'tests', 'select', {})
|
|
124
|
+
assert.strict.deepEqual(r.map((v) => v.id), ['X-r1', 'X-r2'], `opt ${JSON.stringify(opt)}, userId ${String(userId)}`)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
120
127
|
})
|
|
121
128
|
|
|
122
129
|
it('I05 三種hook各自屬於所註冊之實例', async function() {
|
|
123
130
|
//R1、R4: 雙向隔離; 註冊並等待超過1ms後生效
|
|
124
131
|
let log = []
|
|
125
132
|
let calls = []
|
|
126
|
-
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a'
|
|
127
|
-
let B = WServOrm(dsAll, mkWOrm('B', log), 'url-b', 'db-b'
|
|
133
|
+
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a')
|
|
134
|
+
let B = WServOrm(dsAll, mkWOrm('B', log), 'url-b', 'db-b')
|
|
128
135
|
for (let [name, ins] of [['A', A], ['B', B]]) {
|
|
129
136
|
ins.addFunCheck(() => {
|
|
130
137
|
calls.push(`${name}-check`)
|
|
@@ -150,12 +157,12 @@ describe('WServOrm實例互不干擾', function() {
|
|
|
150
157
|
//R1d: A註冊後再建C, C之procOrm不呼叫A之hook
|
|
151
158
|
let log = []
|
|
152
159
|
let calls = []
|
|
153
|
-
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a'
|
|
160
|
+
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a')
|
|
154
161
|
A.addFunCheck(() => {
|
|
155
162
|
calls.push('A-check')
|
|
156
163
|
})
|
|
157
164
|
await wait(20)
|
|
158
|
-
let C = WServOrm(dsAll, mkWOrm('C', log), 'url-c', 'db-c'
|
|
165
|
+
let C = WServOrm(dsAll, mkWOrm('C', log), 'url-c', 'db-c')
|
|
159
166
|
await C.procOrm('u1', 'tests', 'select', {})
|
|
160
167
|
assert.strict.deepEqual(calls, [])
|
|
161
168
|
})
|
|
@@ -178,39 +185,45 @@ describe('WServOrm實例互不干擾', function() {
|
|
|
178
185
|
assert.strict.deepEqual(log, ['W1', 'W2'])
|
|
179
186
|
})
|
|
180
187
|
|
|
181
|
-
it('I08
|
|
182
|
-
//R3: useCheckUser
|
|
183
|
-
let
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
188
|
+
it('I08 擴充函數之參數不含isAdmin', async function() {
|
|
189
|
+
//R3: 隨useCheckUser移除, 參數物件只含woName、userId、mode、input, 後處理另含output
|
|
190
|
+
let A = WServOrm(dsAll, mkWOrm('A', []), 'url-a', 'db-a')
|
|
191
|
+
let ks = {}
|
|
192
|
+
A.addFunCheck((p) => {
|
|
193
|
+
ks.check = Object.keys(p)
|
|
194
|
+
})
|
|
195
|
+
A.addFunPreProcessing((p) => {
|
|
196
|
+
ks.pre = Object.keys(p)
|
|
197
|
+
return p
|
|
198
|
+
})
|
|
199
|
+
A.addFunPostProcessing((p) => {
|
|
200
|
+
ks.post = Object.keys(p)
|
|
201
|
+
return p.output
|
|
202
|
+
})
|
|
203
|
+
await wait(20)
|
|
204
|
+
await A.procOrm('u1', 'tests', 'select', {})
|
|
205
|
+
assert.strict.deepEqual(ks, {
|
|
206
|
+
check: ['woName', 'userId', 'mode', 'input'],
|
|
207
|
+
pre: ['woName', 'userId', 'mode', 'input'],
|
|
208
|
+
post: ['woName', 'userId', 'mode', 'input', 'output'],
|
|
209
|
+
})
|
|
194
210
|
})
|
|
195
211
|
|
|
196
212
|
it('I09 呼叫進行中建立另一實例不影響該次呼叫', async function() {
|
|
197
|
-
//R1a: A
|
|
213
|
+
//R1a: A之check等待中建立B, A之呼叫仍打A之ORM
|
|
198
214
|
let log = []
|
|
199
215
|
let release = null
|
|
200
216
|
let gate = new Promise((resolve) => {
|
|
201
217
|
release = resolve
|
|
202
218
|
})
|
|
203
|
-
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a'
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
getUserById: async () => {
|
|
207
|
-
await gate
|
|
208
|
-
return { isAdmin: 'n', isActive: 'y' }
|
|
209
|
-
},
|
|
219
|
+
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a')
|
|
220
|
+
A.addFunCheck(async () => {
|
|
221
|
+
await gate
|
|
210
222
|
})
|
|
223
|
+
await wait(20)
|
|
211
224
|
let pA = A.procOrm('u1', 'tests', 'select', {})
|
|
212
225
|
await wait(5)
|
|
213
|
-
WServOrm(dsAll, mkWOrm('B', log), 'url-b', 'db-b'
|
|
226
|
+
WServOrm(dsAll, mkWOrm('B', log), 'url-b', 'db-b')
|
|
214
227
|
release()
|
|
215
228
|
let rA = await pA
|
|
216
229
|
assert.strict.deepEqual(log.map((v) => v.name), ['A'])
|
|
@@ -220,8 +233,8 @@ describe('WServOrm實例互不干擾', function() {
|
|
|
220
233
|
it('I10 同一實例之woItems直寫與procOrm寫入打同一個ORM', async function() {
|
|
221
234
|
//R1b: 使用端先以woItems直接寫入再經procOrm寫入之用法
|
|
222
235
|
let log = []
|
|
223
|
-
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a'
|
|
224
|
-
WServOrm(dsAll, mkWOrm('B', log), 'url-b', 'db-b'
|
|
236
|
+
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a')
|
|
237
|
+
WServOrm(dsAll, mkWOrm('B', log), 'url-b', 'db-b')
|
|
225
238
|
await A.woItems.tests.save([{ id: 'x' }])
|
|
226
239
|
await A.procOrm('u1', 'tests', 'save', [{ id: 'y' }])
|
|
227
240
|
assert.strict.deepEqual(log.map((v) => v.name), ['A', 'A'])
|
|
@@ -229,7 +242,7 @@ describe('WServOrm實例互不干擾', function() {
|
|
|
229
242
|
|
|
230
243
|
it('I11 回傳函數之名稱與型別不變', async function() {
|
|
231
244
|
//R2: 使用端以解構取用並當裸函數傳遞; addFun*回傳undefined; procOrm為async函數
|
|
232
|
-
let A = WServOrm(dsAll, mkWOrm('A', []), 'url-a', 'db-a'
|
|
245
|
+
let A = WServOrm(dsAll, mkWOrm('A', []), 'url-a', 'db-a')
|
|
233
246
|
assert.strict.equal(A.procOrm.name, 'procOrm')
|
|
234
247
|
assert.strict.equal(Object.prototype.toString.call(A.procOrm), '[object AsyncFunction]')
|
|
235
248
|
for (let k of ['addFunCheck', 'addFunPreProcessing', 'addFunPostProcessing']) {
|
|
@@ -238,6 +251,55 @@ describe('WServOrm實例互不干擾', function() {
|
|
|
238
251
|
}
|
|
239
252
|
})
|
|
240
253
|
|
|
254
|
+
it('I12 直接呼叫getProc: 已移除之設定與無效之mapOrm皆拋Error, 未給、null或false照常', async function() {
|
|
255
|
+
//R3: 使用端有以getMapOrm與getProc直接組出procOrm者(如w-web-sso之測試), 已移除之設定不得被靜默忽略, 訊息同WServOrm
|
|
256
|
+
//建構期錯誤為Error, 不回rejected Promise(原回之Promise被解構時得undefined)
|
|
257
|
+
let getThrow = (fn) => {
|
|
258
|
+
try {
|
|
259
|
+
fn()
|
|
260
|
+
}
|
|
261
|
+
catch (e) {
|
|
262
|
+
return e
|
|
263
|
+
}
|
|
264
|
+
throw new Error('預期拋錯但未拋')
|
|
265
|
+
}
|
|
266
|
+
let mapOrm = getMapOrm(dsAll, { tests: { select: async () => [{ id: 'r1' }] } })
|
|
267
|
+
let bads = [
|
|
268
|
+
['useCheckUser', true],
|
|
269
|
+
['getUserById', async () => ({ isActive: 'y' })],
|
|
270
|
+
['useExcludeWhenNotAdmin', true],
|
|
271
|
+
]
|
|
272
|
+
for (let [k, v] of bads) {
|
|
273
|
+
let e1 = getThrow(() => getProc(mapOrm, { [k]: v }))
|
|
274
|
+
let e2 = getThrow(() => WServOrm(dsAll, mkWOrm('X', []), 'url-x', 'db-x', { [k]: v }))
|
|
275
|
+
assert.ok(e1 instanceof Error && e1.message.startsWith(`opt.${k} has been removed, `), `${k}: ${String(v)}`)
|
|
276
|
+
assert.strict.equal(e1.message, e2.message)
|
|
277
|
+
}
|
|
278
|
+
for (let bad of [undefined, null, {}, 'x']) {
|
|
279
|
+
let e = getThrow(() => getProc(bad))
|
|
280
|
+
assert.ok(e instanceof Error, String(bad))
|
|
281
|
+
assert.strict.equal(e.message, 'invalid mapOrm')
|
|
282
|
+
}
|
|
283
|
+
for (let args of [[], [undefined], [null], [{}], [{ useCheckUser: false, getUserById: null, useExcludeWhenNotAdmin: false }]]) {
|
|
284
|
+
let { procOrm } = getProc(mapOrm, ...args)
|
|
285
|
+
let r = await procOrm('u1', 'tests', 'select', {})
|
|
286
|
+
assert.strict.deepEqual(r, [{ id: 'r1' }], JSON.stringify(args))
|
|
287
|
+
}
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
it('I13 checkOptRemoved可由使用端單獨呼叫: 只看已移除之三鍵, 其他鍵不受影響', async function() {
|
|
291
|
+
//R3: 使用端包裝層(如WWebApi)以自身之opt呼叫, opt含serverPort等其他鍵; 通過時回undefined且不改動opt
|
|
292
|
+
let optWrap = { serverPort: 11005, webName: { eng: 'x' }, useCheckUser: false, getUserById: null }
|
|
293
|
+
assert.strict.equal(checkOptRemoved(optWrap), undefined)
|
|
294
|
+
assert.strict.deepEqual(optWrap, { serverPort: 11005, webName: { eng: 'x' }, useCheckUser: false, getUserById: null })
|
|
295
|
+
for (let opt of [undefined, null, {}, 'x', 1]) {
|
|
296
|
+
assert.strict.equal(checkOptRemoved(opt), undefined, String(opt))
|
|
297
|
+
}
|
|
298
|
+
for (let k of ['useCheckUser', 'getUserById', 'useExcludeWhenNotAdmin']) {
|
|
299
|
+
assert.throws(() => checkOptRemoved({ serverPort: 11005, [k]: true }), (e) => e instanceof Error && e.message.startsWith(`opt.${k} has been removed, `), k)
|
|
300
|
+
}
|
|
301
|
+
})
|
|
302
|
+
|
|
241
303
|
})
|
|
242
304
|
|
|
243
305
|
|
|
@@ -248,7 +310,7 @@ describe('procOrm後處理', function() {
|
|
|
248
310
|
let log = []
|
|
249
311
|
let calls = []
|
|
250
312
|
let save = (d) => d.map((v, k) => (k === 1 ? { n: 1, ok: 0, err: 'E' } : { n: 1, ok: 1 }))
|
|
251
|
-
let A = WServOrm(dsAll, mkWOrm('A', log, { save }), 'url-a', 'db-a'
|
|
313
|
+
let A = WServOrm(dsAll, mkWOrm('A', log, { save }), 'url-a', 'db-a')
|
|
252
314
|
A.addFunPostProcessing((p) => {
|
|
253
315
|
calls.push(p.mode)
|
|
254
316
|
return p.output
|
|
@@ -270,7 +332,7 @@ describe('mapOrm之log標籤與訊息', function() {
|
|
|
270
332
|
//R6: 標籤依實際操作, reject訊息為該操作之整批失敗訊息
|
|
271
333
|
let log = []
|
|
272
334
|
let fail = () => Promise.reject(new Error('E-batch'))
|
|
273
|
-
let A = WServOrm(dsAll, mkWOrm('A', log, { insert: fail, del: fail }), 'url-a', 'db-a'
|
|
335
|
+
let A = WServOrm(dsAll, mkWOrm('A', log, { insert: fail, del: fail }), 'url-a', 'db-a')
|
|
274
336
|
let errs = []
|
|
275
337
|
let logs = await captureLog(async () => {
|
|
276
338
|
errs.push(await getReject(A.procOrm('u1', 'tests', 'insert', [{ id: 'a' }])))
|
|
@@ -284,7 +346,7 @@ describe('mapOrm之log標籤與訊息', function() {
|
|
|
284
346
|
it('L02 adjustData失敗之標籤含表名', async function() {
|
|
285
347
|
//R6: save、mix之add與diff三處adjustData失敗皆記表名, reject訊息為整批失敗訊息
|
|
286
348
|
let log = []
|
|
287
|
-
let A = WServOrm({ tests: {} }, mkWOrm('A', log), 'url-a', 'db-a'
|
|
349
|
+
let A = WServOrm({ tests: {} }, mkWOrm('A', log), 'url-a', 'db-a')
|
|
288
350
|
let errs = []
|
|
289
351
|
let logs = await captureLog(async () => {
|
|
290
352
|
errs.push(await getReject(A.procOrm('u1', 'tests', 'save', [{ id: 'a' }])))
|
|
@@ -300,7 +362,7 @@ describe('mapOrm之log標籤與訊息', function() {
|
|
|
300
362
|
let id150 = 'k'.repeat(150)
|
|
301
363
|
let id100 = 'm'.repeat(100)
|
|
302
364
|
let save = (d) => d.map(() => ({ n: 1, ok: 0, err: 'E' }))
|
|
303
|
-
let A = WServOrm(dsAll, mkWOrm('A', [], { save }), 'url-a', 'db-a'
|
|
365
|
+
let A = WServOrm(dsAll, mkWOrm('A', [], { save }), 'url-a', 'db-a')
|
|
304
366
|
let err1 = null
|
|
305
367
|
let err2 = null
|
|
306
368
|
let logs = await captureLog(async () => {
|
|
@@ -322,7 +384,7 @@ describe('procOrm補主鍵', function() {
|
|
|
322
384
|
it('P01 insert、save、mix之新增未帶主鍵時補值並回傳', async function() {
|
|
323
385
|
//D1: 本套件以genIDSeq補值, 回傳之id即ORM收到之id; 物件輸入回傳單一{id}
|
|
324
386
|
let log = []
|
|
325
|
-
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a'
|
|
387
|
+
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a')
|
|
326
388
|
let r1 = await A.procOrm('u1', 'tests', 'insert', [{ name: 'a' }])
|
|
327
389
|
let r2 = await A.procOrm('u1', 'tests', 'save', { name: 'b' })
|
|
328
390
|
let r3 = await A.procOrm('u1', 'tests', 'mix', { add: [{ name: 'c' }] })
|
|
@@ -335,7 +397,7 @@ describe('procOrm補主鍵', function() {
|
|
|
335
397
|
it('P02 依主鍵值決定是否補值', async function() {
|
|
336
398
|
//D1: null、空字串、物件補值; 數字與非空字串保留(reladb、mdb視數字為有效主鍵)
|
|
337
399
|
let log = []
|
|
338
|
-
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a'
|
|
400
|
+
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a')
|
|
339
401
|
let input = [{ id: null }, { id: '' }, { id: { x: 1 } }, { id: 123 }, { id: 'keep' }]
|
|
340
402
|
let r = await A.procOrm('u1', 'tests', 'save', input)
|
|
341
403
|
let got = log[0].data.map((v) => v.id)
|
|
@@ -357,7 +419,7 @@ describe('procOrm補主鍵', function() {
|
|
|
357
419
|
]
|
|
358
420
|
for (let [ds, expectGen] of dsCases) {
|
|
359
421
|
log.length = 0
|
|
360
|
-
let A = WServOrm(ds, mkWOrm('A', log), 'url-a', 'db-a'
|
|
422
|
+
let A = WServOrm(ds, mkWOrm('A', log), 'url-a', 'db-a')
|
|
361
423
|
await A.procOrm('u1', 'tests', 'insert', [{ name: 'a' }])
|
|
362
424
|
assert.strict.equal(isId(log[0].data[0].id), expectGen, JSON.stringify(ds))
|
|
363
425
|
}
|
|
@@ -366,7 +428,7 @@ describe('procOrm補主鍵', function() {
|
|
|
366
428
|
it('P04 單一空物件維持原樣交ORM', async function() {
|
|
367
429
|
//D1: 調整後無欄位之列不補, 保留ORM視空物件為無效輸入之既有行為
|
|
368
430
|
let log = []
|
|
369
|
-
let A = WServOrm({ tests: { keys: ['id', 'name'] } }, mkWOrm('A', log), 'url-a', 'db-a'
|
|
431
|
+
let A = WServOrm({ tests: { keys: ['id', 'name'] } }, mkWOrm('A', log), 'url-a', 'db-a')
|
|
370
432
|
await A.procOrm('u1', 'tests', 'save', {})
|
|
371
433
|
assert.strict.deepEqual(log[0].data, {})
|
|
372
434
|
})
|
|
@@ -374,7 +436,7 @@ describe('procOrm補主鍵', function() {
|
|
|
374
436
|
it('P05 同批多筆各自補值且呼叫端原物件不被加上主鍵', async function() {
|
|
375
437
|
//D1、D1a: 各自唯一; 補值寫在複本, 呼叫端原物件不含補出之主鍵
|
|
376
438
|
let log = []
|
|
377
|
-
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a'
|
|
439
|
+
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a')
|
|
378
440
|
let input = [{ name: 'a' }, { name: 'b' }, { name: 'c' }]
|
|
379
441
|
let r = await A.procOrm('u1', 'tests', 'insert', input)
|
|
380
442
|
let ids = r.map((v) => v.id)
|
|
@@ -386,7 +448,7 @@ describe('procOrm補主鍵', function() {
|
|
|
386
448
|
//X2: 呼叫端未帶主鍵者仍列第N筆, log保留補出之主鍵
|
|
387
449
|
let log = []
|
|
388
450
|
let save = (d) => d.map((v, k) => (k === 1 ? { n: 1, ok: 0, err: 'E' } : { n: 1, ok: 1 }))
|
|
389
|
-
let A = WServOrm(dsAll, mkWOrm('A', log, { save }), 'url-a', 'db-a'
|
|
451
|
+
let A = WServOrm(dsAll, mkWOrm('A', log, { save }), 'url-a', 'db-a')
|
|
390
452
|
let err = null
|
|
391
453
|
let logs = await captureLog(async () => {
|
|
392
454
|
err = await getReject(A.procOrm('u1', 'tests', 'save', [{ id: 's1' }, { name: 'no-id' }]))
|
|
@@ -405,7 +467,7 @@ describe('hook串接與註冊', function() {
|
|
|
405
467
|
it('K01 多個模組各註冊一個後處理皆正確', async function() {
|
|
406
468
|
//D3: 每個後處理皆收參數物件, output為前一個之回傳值
|
|
407
469
|
let log = []
|
|
408
|
-
let A = WServOrm(dsTwo, mkWOrm('A', log), 'url-a', 'db-a'
|
|
470
|
+
let A = WServOrm(dsTwo, mkWOrm('A', log), 'url-a', 'db-a')
|
|
409
471
|
A.addFunPostProcessing(({ woName, output }) => (woName !== 'users' ? output : output.map((v) => ({ ...v, tagA: 1 }))))
|
|
410
472
|
A.addFunPostProcessing(({ woName, output }) => (woName !== 'items' ? output : output.map((v) => ({ ...v, tagB: 1 }))))
|
|
411
473
|
await wait(20)
|
|
@@ -418,7 +480,7 @@ describe('hook串接與註冊', function() {
|
|
|
418
480
|
it('K02 後處理回傳undefined往下傳且拋錯即中止', async function() {
|
|
419
481
|
//D3: 不加特例; 某個拋錯則procOrm reject且後續不執行
|
|
420
482
|
let calls = []
|
|
421
|
-
let A = WServOrm(dsAll, mkWOrm('A', []), 'url-a', 'db-a'
|
|
483
|
+
let A = WServOrm(dsAll, mkWOrm('A', []), 'url-a', 'db-a')
|
|
422
484
|
A.addFunPostProcessing(() => undefined)
|
|
423
485
|
A.addFunPostProcessing((p) => {
|
|
424
486
|
calls.push(p.output)
|
|
@@ -428,7 +490,7 @@ describe('hook串接與註冊', function() {
|
|
|
428
490
|
let r = await A.procOrm('u1', 'tests', 'select', {})
|
|
429
491
|
assert.strict.equal(r, undefined)
|
|
430
492
|
assert.strict.deepEqual(calls, [undefined])
|
|
431
|
-
let B = WServOrm(dsAll, mkWOrm('B', []), 'url-b', 'db-b'
|
|
493
|
+
let B = WServOrm(dsAll, mkWOrm('B', []), 'url-b', 'db-b')
|
|
432
494
|
let after = []
|
|
433
495
|
B.addFunPostProcessing(() => {
|
|
434
496
|
throw new Error('E-post')
|
|
@@ -447,7 +509,7 @@ describe('hook串接與註冊', function() {
|
|
|
447
509
|
//P3-3: 前一個只回{input}時, 下一個仍收得到woName
|
|
448
510
|
let log = []
|
|
449
511
|
let seen = []
|
|
450
|
-
let A = WServOrm(dsTwo, mkWOrm('A', log), 'url-a', 'db-a'
|
|
512
|
+
let A = WServOrm(dsTwo, mkWOrm('A', log), 'url-a', 'db-a')
|
|
451
513
|
A.addFunPreProcessing((p) => ({ input: p.input.map((v) => ({ ...v, preA: 1 })) }))
|
|
452
514
|
A.addFunPreProcessing((p) => {
|
|
453
515
|
seen.push(p.woName)
|
|
@@ -464,7 +526,7 @@ describe('hook串接與註冊', function() {
|
|
|
464
526
|
//P3-3: 防止input成為undefined而令select回全表
|
|
465
527
|
for (let bad of [undefined, [1], { woName: 'tests' }]) {
|
|
466
528
|
let log = []
|
|
467
|
-
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a'
|
|
529
|
+
let A = WServOrm(dsAll, mkWOrm('A', log), 'url-a', 'db-a')
|
|
468
530
|
A.addFunPreProcessing(() => bad)
|
|
469
531
|
await wait(20)
|
|
470
532
|
let err = await getReject(A.procOrm('u1', 'tests', 'select', {}))
|
|
@@ -480,7 +542,7 @@ describe('hook串接與註冊', function() {
|
|
|
480
542
|
release = resolve
|
|
481
543
|
})
|
|
482
544
|
let calls = []
|
|
483
|
-
let A = WServOrm(dsAll, mkWOrm('A', []), 'url-a', 'db-a'
|
|
545
|
+
let A = WServOrm(dsAll, mkWOrm('A', []), 'url-a', 'db-a')
|
|
484
546
|
A.addFunPostProcessing(async (p) => {
|
|
485
547
|
calls.push('h1')
|
|
486
548
|
await gate
|
|
@@ -503,13 +565,13 @@ describe('hook串接與註冊', function() {
|
|
|
503
565
|
|
|
504
566
|
it('K06 註冊非函數即同步拋錯, 函數與async函數可註冊', async function() {
|
|
505
567
|
//D4: 訊息含hook名稱; 合法註冊之實例另建(A之check已因非函數註冊而被守門, 見K07)
|
|
506
|
-
let A = WServOrm(dsAll, mkWOrm('A', []), 'url-a', 'db-a'
|
|
568
|
+
let A = WServOrm(dsAll, mkWOrm('A', []), 'url-a', 'db-a')
|
|
507
569
|
for (let k of ['addFunCheck', 'addFunPreProcessing', 'addFunPostProcessing']) {
|
|
508
570
|
for (let bad of [undefined, null, 'x', {}]) {
|
|
509
571
|
assert.throws(() => A[k](bad), (e) => e instanceof Error && e.message.includes(k))
|
|
510
572
|
}
|
|
511
573
|
}
|
|
512
|
-
let B = WServOrm(dsAll, mkWOrm('B', []), 'url-b', 'db-b'
|
|
574
|
+
let B = WServOrm(dsAll, mkWOrm('B', []), 'url-b', 'db-b')
|
|
513
575
|
for (let k of ['addFunCheck', 'addFunPreProcessing', 'addFunPostProcessing']) {
|
|
514
576
|
B[k](function(p) {
|
|
515
577
|
return k === 'addFunCheck' ? undefined : (k === 'addFunPreProcessing' ? p : p.output)
|
|
@@ -523,7 +585,7 @@ describe('hook串接與註冊', function() {
|
|
|
523
585
|
|
|
524
586
|
it('K07 check註冊失敗被吞掉仍擋下呼叫, 前後處理則不影響', async function() {
|
|
525
587
|
//P3-4: check維持fail-closed; 前後處理註冊失敗時陣列不變
|
|
526
|
-
let A = WServOrm(dsAll, mkWOrm('A', []), 'url-a', 'db-a'
|
|
588
|
+
let A = WServOrm(dsAll, mkWOrm('A', []), 'url-a', 'db-a')
|
|
527
589
|
try {
|
|
528
590
|
A.addFunCheck(null)
|
|
529
591
|
}
|
|
@@ -533,7 +595,7 @@ describe('hook串接與註冊', function() {
|
|
|
533
595
|
assert.ok(String(err).includes('addFunCheck'))
|
|
534
596
|
//錯誤型別: 守門於procOrm內reject, 與procOrm其餘拒絕一致為字串
|
|
535
597
|
assert.strict.equal(typeof err, 'string')
|
|
536
|
-
let B = WServOrm(dsAll, mkWOrm('B', []), 'url-b', 'db-b'
|
|
598
|
+
let B = WServOrm(dsAll, mkWOrm('B', []), 'url-b', 'db-b')
|
|
537
599
|
for (let k of ['addFunPreProcessing', 'addFunPostProcessing']) {
|
|
538
600
|
try {
|
|
539
601
|
B[k](null)
|
|
@@ -545,10 +607,4 @@ describe('hook串接與註冊', function() {
|
|
|
545
607
|
assert.strict.equal(r.length, 2)
|
|
546
608
|
})
|
|
547
609
|
|
|
548
|
-
it('K08 src/getItemsFail.mjs相容檔轉出w-data-collector之版本', async function() {
|
|
549
|
-
//X1: 使用端以深層路徑引用(如w-web-sso server/ormWrite.mjs)
|
|
550
|
-
let m = await import('../src/getItemsFail.mjs')
|
|
551
|
-
assert.strict.equal(m.default, getItemsFailWdc)
|
|
552
|
-
})
|
|
553
|
-
|
|
554
610
|
})
|
|
@@ -4,7 +4,7 @@ import genTestData from '../src/genTestData.mjs'
|
|
|
4
4
|
import dsSchema from '../schema/index.mjs'
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
//替身ORM, 回傳形狀依w-orm系列規格(
|
|
7
|
+
//替身ORM, 回傳形狀依w-orm系列規格(w-orm系列套件統一規格.md T2、T4):
|
|
8
8
|
//save與del回傳與輸入等長保序之逐筆陣列, 單筆失敗時整批仍resolve, 該筆以ok為0並附err回報; 整批性錯誤則reject
|
|
9
9
|
let plan = {}
|
|
10
10
|
let calls = []
|
|
@@ -41,7 +41,7 @@ async function getReject(pm) {
|
|
|
41
41
|
|
|
42
42
|
describe('mapOrm逐筆失敗', function() {
|
|
43
43
|
|
|
44
|
-
let so = WServOrm(ds, WOrmStub, 'stub-url', 'stub-db'
|
|
44
|
+
let so = WServOrm(ds, WOrmStub, 'stub-url', 'stub-db')
|
|
45
45
|
let proc = (mode, input) => so.procOrm('u1', 'tests', mode, input)
|
|
46
46
|
|
|
47
47
|
beforeEach(function() {
|
|
@@ -232,7 +232,7 @@ describe('mapOrm逐筆失敗', function() {
|
|
|
232
232
|
|
|
233
233
|
describe('mapOrm主鍵與clearXSS', function() {
|
|
234
234
|
|
|
235
|
-
let so = WServOrm(ds, WOrmStub, 'stub-url', 'stub-db'
|
|
235
|
+
let so = WServOrm(ds, WOrmStub, 'stub-url', 'stub-db')
|
|
236
236
|
let proc = (mode, input) => so.procOrm('u1', 'tests', mode, input)
|
|
237
237
|
|
|
238
238
|
beforeEach(function() {
|