w-orm-lowdb 1.0.33 → 1.0.35

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.
@@ -5,6 +5,8 @@ import w from 'wsemi'
5
5
  import cvCases from 'wsemi/src/_cvOrmFindCases.mjs'
6
6
  import cvOrmFind from 'wsemi/src/cvOrmFind.mjs'
7
7
  import WOrm from '../src/WOrmLowdb.mjs'
8
+ import { tick, mkObserver } from './lib/mkObserver.mjs'
9
+ import { leaves, chkSame } from './lib/leaves.mjs'
8
10
 
9
11
 
10
12
  //條件(find)之系列白名單(帳本R-FIND-01; 規則: C:\opensrcOper\dspec\w-orm系列條件語法支援盤點.md〈一之三〉)
@@ -20,9 +22,6 @@ describe('find-whitelist', function() {
20
22
  //ids, 取id集合(升冪)
21
23
  let ids = (rs) => rs.map((v) => v.id).sort()
22
24
 
23
- //tick, 讓出一個macrotask, 令延遲發出之事件有機會發出
24
- let tick = () => new Promise((resolve) => setTimeout(resolve, 0))
25
-
26
25
  //directMsg, 共用檢核對同一條件直接給出之訊息(後端須原樣給出, 不得改寫、包裝或另立訊息)
27
26
  let directMsg = (f) => {
28
27
  try {
@@ -34,46 +33,6 @@ describe('find-whitelist', function() {
34
33
  return null
35
34
  }
36
35
 
37
- //mkObserver, 建立呼叫觀測器: 事件記錄於evs, 每筆error事件附帶發出當下呼叫端之await是否已恢復(settledAtEmit, 即呼叫端可觀察之先後)
38
- let mkObserver = (wo) => {
39
- let evs = []
40
- let cur = { settled: false }
41
- wo.on('error', function(mode, data, err) {
42
- evs.push({ t: 'error', mode, data, err, settledAtEmit: cur.settled })
43
- })
44
- wo.on('change', function(mode) {
45
- evs.push({ t: 'change', mode })
46
- })
47
-
48
- //invoke, 呼叫wo[fn](arg)並回傳{ ok, val, err, nAtSettle, probe, evs }, nAtSettle為結果定案當下之事件數,
49
- //probe為結果定案當下(同一microtask鏈內, 尚未讓出macrotask)呼叫probeFn()之回傳, evs為再讓出一個macrotask後之事件
50
- let invoke = async(fn, arg, probeFn = null) => {
51
- evs.length = 0
52
- cur = { settled: false }
53
- let out = { ok: false, val: null, err: null, nAtSettle: 0, probe: null, evs: [] }
54
- try {
55
- out.val = await wo[fn](arg)
56
- out.ok = true
57
- }
58
- catch (err) {
59
- out.err = err
60
- }
61
- cur.settled = true
62
- out.nAtSettle = evs.length
63
- out.probe = probeFn ? probeFn() : null
64
- await tick()
65
- out.evs = evs.slice()
66
- return out
67
- }
68
-
69
- //clear
70
- let clear = () => {
71
- evs.length = 0
72
- }
73
-
74
- return { invoke, clear }
75
- }
76
-
77
36
  //mk, 於測試資料夾下建立資料庫檔(url為檔案路徑)
78
37
  let mk = (name, opt = {}) => {
79
38
  let url = `${dir}/${name}.json`
@@ -665,32 +624,6 @@ describe('find-whitelist', function() {
665
624
  })
666
625
  }
667
626
 
668
- //leaves與chkSame: 取條件物件之全部節點(物件節點記鍵序,Date節點記毫秒,皆記參照), 供reject後確認呼叫端實際傳入之同一物件逐節點未被改動
669
- let leaves = (v, p = 'find', out = []) => {
670
- if (v instanceof Date) {
671
- out.push({ p, ref: v, ms: v.getTime() })
672
- }
673
- else if (v !== null && typeof v === 'object') {
674
- out.push({ p, ref: v, keys: Object.keys(v).join(',') })
675
- for (let k of Object.keys(v)) {
676
- leaves(v[k], `${p}.${k}`, out)
677
- }
678
- }
679
- else {
680
- out.push({ p, ref: v })
681
- }
682
- return out
683
- }
684
- let chkSame = (a, b) => {
685
- assert.strict.equal(a.length, b.length, 'find should keep the same number of nodes')
686
- for (let i = 0; i < a.length; i++) {
687
- assert.strict.equal(a[i].p, b[i].p)
688
- assert.strict.equal(a[i].ref, b[i].ref, `${a[i].p} should keep the same reference or value`)
689
- assert.strict.equal(a[i].ms, b[i].ms, `${a[i].p} should keep the same time value`)
690
- assert.strict.equal(a[i].keys, b[i].keys, `${a[i].p} should keep the same keys`)
691
- }
692
- }
693
-
694
627
  //reject: 範圍外Date於各位置, select與delAll皆整批reject, 訊息含路徑且不回顯值, error事件於reject前恰一次, 不發change, 資料不變
695
628
  let bads = [
696
629
  { name: 'below 0000 (-000001-12-31T23:59:59.999Z)', ms: MS.belowMin, echo: ['000001'] },
@@ -874,28 +807,19 @@ describe('find-whitelist', function() {
874
807
  })
875
808
  }
876
809
 
877
- //數據側(R-FIND-02規則5): 範圍外Date之寫入行為不變, 惟其資料無法以Date條件正確比較(文件已載明)
878
- it('should keep writing out-of-range Date as signed ISO string and document that such data can not be compared by Date condition', async function() {
810
+ //數據側(R-FIND-02規則5; 寫入側見R-DATE-01與unit-date-write): 資料庫檔內既有之範圍外Date字串(舊版寫入之樣子; 現行寫入已拒收範圍外Date物件,
811
+ //惟字串不是Date物件故仍可寫入)無法以Date條件正確比較(文件已載明)
812
+ it('should document that out-of-range Date strings already in database can not be compared by Date condition', async function() {
879
813
  let w1 = mk('daterange-data').wo
880
- //三個寫入入口(insertBulk、insert、save之更新與自動插入)皆不檢核資料側之Date, 範圍外者照存為帶正負號之ISO字串
881
814
  await w1.insertBulk([
882
- { id: 's1', t: D(MS.big) },
883
- { id: 's2', t: D(MS.small) },
815
+ { id: 's1', t: '+275760-09-13T00:00:00.000Z' }, //舊版以new Date(8.64e15)寫入之樣子
816
+ { id: 's2', t: '-271821-04-20T00:00:00.000Z' }, //舊版以new Date(-8.64e15)寫入之樣子
884
817
  { id: 'n1', t: D(Date.UTC(2020, 0, 1)) },
885
818
  { id: 'nul', t: null },
886
819
  { id: 'max9999', t: new Date('9999-12-31T23:59:59.999Z') },
887
820
  ])
888
821
  assert.strict.equal((await w1.selectByPk('s1')).t, '+275760-09-13T00:00:00.000Z')
889
822
  assert.strict.equal((await w1.selectByPk('s2')).t, '-271821-04-20T00:00:00.000Z')
890
- await w1.insert({ id: 'i1', t: D(MS.aboveMax) })
891
- assert.strict.equal((await w1.selectByPk('i1')).t, '+010000-01-01T00:00:00.000Z')
892
- await w1.save({ id: 'sv1', t: D(MS.belowMin) }) //自動插入
893
- assert.strict.equal((await w1.selectByPk('sv1')).t, '-000001-12-31T23:59:59.999Z')
894
- await w1.save({ id: 'n1', t: D(MS.big) }) //更新既有
895
- assert.strict.equal((await w1.selectByPk('n1')).t, '+275760-09-13T00:00:00.000Z')
896
- await w1.save({ id: 'n1', t: D(Date.UTC(2020, 0, 1)) }) //改回範圍內
897
- assert.strict.equal((await w1.selectByPk('n1')).t, '2020-01-01T00:00:00.000Z')
898
- await w1.delAll({ id: { $in: ['i1', 'sv1'] } })
899
823
 
900
824
  //範圍內之條件值被接受, 但正年份哨兵s1(+275760年, 時間序屬未來)因字串字典序小於'2026-…'而被$lt現在命中(此即文件所載之限制, 非本檢核可防);
901
825
  //s2(-271821年)雖亦命中, 但屬時間序之過去, 結果碰巧正確; null與範圍內最大日期(9999年底)不被命中(文件建議之永不過期寫法)