node-red-contrib-prib-functions 0.18.0 → 0.20.4

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.
Files changed (87) hide show
  1. package/.github/workflows/codeql-analysis.yml +3 -3
  2. package/.github/workflows/npmpublish.yml +6 -6
  3. package/.vs/VSWorkspaceState.json +7 -0
  4. package/.vs/node-red-contrib-prib-functions/v17/.wsuo +0 -0
  5. package/README.md +22 -19
  6. package/arima/index.js +18 -0
  7. package/dataAnalysis/arrayAllRowsSwap.js +15 -0
  8. package/dataAnalysis/arrayCompareToPrecision.js +34 -0
  9. package/dataAnalysis/arrayDifference.js +14 -0
  10. package/dataAnalysis/arrayDifferenceSeasonal.js +15 -0
  11. package/dataAnalysis/arrayDifferenceSeasonalSecondOrder.js +20 -0
  12. package/dataAnalysis/arrayDifferenceSecondOrder.js +14 -0
  13. package/dataAnalysis/arrayForEachRange.js +38 -0
  14. package/dataAnalysis/arrayOverlay.js +13 -0
  15. package/dataAnalysis/arrayProduct.js +11 -0
  16. package/dataAnalysis/arrayRandom.js +14 -0
  17. package/dataAnalysis/arrayReduceRange.js +11 -0
  18. package/dataAnalysis/arrayScale.js +11 -0
  19. package/dataAnalysis/arraySum.js +11 -0
  20. package/dataAnalysis/arraySumSquared.js +11 -0
  21. package/dataAnalysis/arraySwap.js +11 -0
  22. package/dataAnalysis/dataAnalysis.html +31 -14
  23. package/dataAnalysis/dataAnalysis.js +10 -1
  24. package/dataAnalysis/generateMatrixFunction.js +89 -0
  25. package/dataAnalysis/generateVectorFunction.js +25 -0
  26. package/dataAnalysis/pca.js +546 -0
  27. package/dataAnalysis/svd.js +239 -0
  28. package/documentation/loadInjector.png +0 -0
  29. package/echart/echart.html +68 -0
  30. package/echart/echart.js +85 -0
  31. package/echart/icons/chart-671.png +0 -0
  32. package/echart/lib/echarts.js +95886 -0
  33. package/lib/Chart.js +177 -0
  34. package/lib/Column.js +99 -0
  35. package/lib/GraphDB.js +14 -0
  36. package/lib/Table.js +185 -0
  37. package/lib/objectExtensions.js +361 -0
  38. package/matrix/matrix.js +50 -50
  39. package/matrix/matrixNode.html +144 -154
  40. package/matrix/matrixNode.js +26 -9
  41. package/monitor/BarGauge.js +8 -0
  42. package/monitor/Dataset.js +29 -0
  43. package/monitor/DialGauge.js +109 -0
  44. package/monitor/DialNeedle.js +36 -0
  45. package/monitor/Format.js +74 -0
  46. package/monitor/centerElement.js +14 -0
  47. package/monitor/compareElements.js +95 -0
  48. package/monitor/defs.js +23 -0
  49. package/monitor/extensions.js +906 -0
  50. package/monitor/functions.js +36 -0
  51. package/monitor/json2xml.js +103 -0
  52. package/monitor/monitorSystem.html +198 -0
  53. package/monitor/monitorSystem.js +322 -0
  54. package/monitor/svgHTML.js +179 -0
  55. package/monitor/svgObjects.js +64 -0
  56. package/package.json +31 -8
  57. package/test/00-objectExtensions.js +94 -0
  58. package/test/01-base.js +88 -0
  59. package/test/04-tables.js +33 -0
  60. package/test/data/.config.nodes.json +608 -0
  61. package/test/data/.config.nodes.json.backup +608 -0
  62. package/test/data/.config.runtime.json +4 -0
  63. package/test/data/.config.runtime.json.backup +3 -0
  64. package/test/data/.config.users.json +21 -0
  65. package/test/data/.config.users.json.backup +21 -0
  66. package/test/data/.flow.json.backup +3433 -0
  67. package/test/data/float32vector10.npy +0 -0
  68. package/test/data/flow.json +3433 -0
  69. package/test/data/int2matrix2x3.npy +0 -0
  70. package/test/data/package-lock.json +158 -0
  71. package/test/data/package.json +11 -0
  72. package/test/data/settings.js +544 -0
  73. package/test/dataAnalysisExtensions.js +472 -0
  74. package/test/dataAnalysisPCA.js +54 -0
  75. package/test/dataAnalysisSVD.js +31 -0
  76. package/test/euclideanDistance.js +2 -2
  77. package/test/matrix/02base.js +36 -0
  78. package/test/transformNumPy.js +132 -0
  79. package/testing/data/countries.csv +250 -0
  80. package/testing/hostAvailable.html +0 -2
  81. package/testing/load-injector.html +76 -21
  82. package/testing/load-injector.js +35 -54
  83. package/testing/test.js +1 -0
  84. package/transform/NumPy.js +303 -0
  85. package/transform/transform.html +73 -19
  86. package/transform/transform.js +144 -8
  87. package/documentation/LoadInjector.JPG +0 -0
@@ -0,0 +1,179 @@
1
+ const { action } = require("./defs");
2
+
3
+ function drawSVGElement(element,p,baseId) {
4
+ if(p==null) throw Error("No properities")
5
+ const el=typeof element === "string"?document.getElementById(element):element
6
+ if(el==null) throw Error("element not found or null for "+element)
7
+ if (p.constructor === String)
8
+ return el.appendChild(document.createTextNode(p));
9
+ if(p instanceof Array) {
10
+ for(var i=0;i<p.length;i++) {
11
+ drawSVGElement(el,p[i],baseId);
12
+ }
13
+ return;
14
+ }
15
+ if(p.action=="clear"){
16
+ el.parentNode.replaceChild(el.cloneNode(false), el);
17
+ return;
18
+ }
19
+ if(p.action=="update"){
20
+ return updateSVGElement(el,p,baseId)
21
+ }
22
+ if(["setStyle","setConicGradient"].includes(p.action)){
23
+ return drawSVGElement(el,getSetStyle("#"+baseId+p.id),baseId)
24
+ }
25
+ let newEl = document.createElementNS("http://www.w3.org/2000/svg", p.action);
26
+ if(newEl==undefined) throw Error("svg invalid function "+p.action);
27
+ updateSVGElement(newEl,p,baseId)
28
+ el.appendChild(newEl);
29
+ return newEl;
30
+ };
31
+ function getSVGTransform(t){
32
+ const result= (t.translate?(" translate( " + (t.translate.x??0) + " "+ (t.translate.y??" ")+")" ):"") +
33
+ (t.scale?(" scale( "+t.scale.x+" "+(t.scale.y??" ")+")"):"") +
34
+ (t.rotate?(" rotate( "+t.rotate.angle+" "+(t.rotate.x??" ")+" "+(t.rotate.y??" ")+")"):"") +
35
+ (t.matrix?(" matrix( "+t.matrix.map(c=>c instanceof Array?c.join(","):c).join(" ")+")"):"") +
36
+ (t.skewX?(" skewX( "+t.skewX+")"):"") +
37
+ (t.skewY?(" skewY( "+t.skewY+")"):"")
38
+ if(result=="") throw Error("no valid transform for "+t)
39
+ return result
40
+ }
41
+ const svgArray2Points=(a)=>a.map(c=>c.join(',')).join(" ")
42
+
43
+ function getSVGPath(t){
44
+ return t.reduce((p,c,i)=>{
45
+ if(typeof c !== "object") return p+" "+ c
46
+ if(c instanceof Array) {
47
+ // if(c.length && c[0] instanceof Array) return p+" "+getSVGPath(c)
48
+ // return p+" "+c.join(" ")
49
+ return p+" "+getSVGPath(c)
50
+ }
51
+ try{
52
+ switch (c.action){
53
+ case "M":
54
+ case "moveTo":
55
+ return p+"M "+c.x+" "+c.y+" "
56
+ case "m":
57
+ case "deltaMoveTo":
58
+ return p+"m "+c.x+" "+c.y+" "
59
+ case "L":
60
+ case "lineTo":
61
+ return p+"L "+c.x+" "+c.y+" "
62
+ case "l":
63
+ case "deltaLineTo":
64
+ return p+"l "+c.x+" "+c.y+" "
65
+ case "H":
66
+ case "horizontalLineTo":
67
+ return p+"H "+c+" "
68
+ case "h":
69
+ case "deltaHorizontalLineTo":
70
+ return p+"h "+c+" "
71
+ case "V":
72
+ case "verticalLineTo":
73
+ return p+"V "+c+" "
74
+ case "v":
75
+ case "deltaVerticalLineTo":
76
+ return p+"h "+c+" "
77
+ case "A":
78
+ case "arc":
79
+ return p+"A "+c.radius.x+" "+c.radius.y+" "+(c.angle??0)+" "+(c.large?1:0)+" "+(c.sweep?1:0)+c.x+" "+c.y+" "
80
+ case "a":
81
+ case "deltaArc":
82
+ return p+"a "+c.radius.x+" "+c.radius.y+" "+(c.angle??0)+" "+(c.large?1:0)+" "+(c.sweep?1:0)+c.x+" "+c.y+" "
83
+ case "Q":
84
+ return p+"Q "+c.x1+" "+c.y1+" "+c.x+" "+c.y+" "
85
+ case "q":
86
+ return p+"q "+c.x1+" "+c.y1+" "+c.x+" "+c.y+" "
87
+ case "T":
88
+ return p+"T "+c.x+" "+c.y+" "
89
+ case "t":
90
+ return p+"t "+c.x+" "+c.y+" "
91
+ case "C":
92
+ return p+"C "+c.x1+" "+c.y1+" "+c.x2+" "+c.y2+" "+c.x+" "+c.y+" "
93
+ case "c":
94
+ return p+"c "+c.x1+" "+c.y1+" "+c.x2+" "+c.y2+" "+c.x+" "+c.y+" "
95
+ case "S":
96
+ return p+"S "+c.x2+" "+c.y2+" "+c.x+" "+c.y+" "
97
+ case "s":
98
+ return p+"s "+c.x2+" "+c.y2+" "+c.x+" "+c.y+" "
99
+ case "Z":
100
+ case "z":
101
+ case "close":
102
+ return p+"Z "
103
+ default: throw Error("unknown path action: "+c.action)
104
+ }
105
+ } catch(ex) {
106
+ throw Error(ex.message+ " in "+JSON.stringify(c))
107
+ }
108
+ },"")
109
+ }
110
+ function updateSVGElement(element,p,baseId="") {
111
+ if(p.action=="update" && p.id) {
112
+ element= document.getElementById(baseId+p.id)
113
+ if(element==null) throw Error("element id not found for "+baseId+p.id)
114
+ if(element instanceof SVGTextElement) {
115
+ while (element.firstChild) {
116
+ element.removeChild(element.firstChild);
117
+ }
118
+ }
119
+ }
120
+ const el=typeof element === "string"?document.getElementById(baseId+element):element
121
+ if(el==null) throw Error("element not found or null for "+baseId+element)
122
+ for(var a in p){
123
+ if(a=="action") continue;
124
+ if(a=="children" && p[a] instanceof Array) {
125
+ drawSVGElement(el,p[a],baseId);
126
+ continue;
127
+ }
128
+ if(a instanceof Function) {
129
+ el.addEventListener((p.substr(0,2)=="on"?p.substr(2):p), a.bind(this), false);
130
+ continue;
131
+ }
132
+ const pa=p[a]
133
+ if(typeof pa==="object"){
134
+ switch (a) {
135
+ case "points":
136
+ el.setAttributeNS(null, a, svgArray2Points(pa));
137
+ continue
138
+ case "path":
139
+ case "d":
140
+ const path=getSVGPath(pa)
141
+ el.setAttributeNS(null, a, path)
142
+ continue
143
+ case "href":
144
+ el.setAttributeNS(null, a, "url("+pa.id?"#"+ baseId+pa.id +")":"" )
145
+ continue
146
+ case "transform":
147
+ const v=getSVGTransform(pa)
148
+ el.setAttributeNS(null, a, v);
149
+ continue
150
+ case "viewBox":
151
+ el.setAttributeNS(null, a, svgArray2Points((pa.x??0)+" "+(pa.y??0) +" "+(pa.width??0)+" "+(pa.height??0)));
152
+ continue
153
+ case "stroke":
154
+ let style=""
155
+ if(pa.class) style+="url(."+baseId+pa.url+")"
156
+ if(pa.element) style+="url(#"+baseId+pa.element+")"
157
+ el.setAttributeNS(null, a, style);
158
+ continue
159
+ default:
160
+ throw Error("unknown "+p.action+" property"+a)
161
+ }
162
+ }
163
+ try{
164
+ el.setAttributeNS(null, a, (a=="id"?baseId:"")+pa);
165
+ } catch(ex) {
166
+ throw Error("failed set attribute "+a+" to "+pa+" error "+ex.message)
167
+ }
168
+ }
169
+ switch (p.action){
170
+ case "foreignObject" :
171
+ el.setAttributeNS(null, "requiredExtensions", "http://www.w3.org/1999/xhtml");
172
+ break;
173
+ }
174
+ return el;
175
+ };
176
+
177
+ const getSetStyle = (id,value="background: conic-gradient(red, orange, yellow, green);")=>{
178
+ return {action:"style",children:[id+" { "+value+" }"]}
179
+ }
@@ -0,0 +1,64 @@
1
+ const { off } = require("process")
2
+ const { isAsyncFunction } = require("util/types")
3
+ const Dataset=require("./Dataset.js")
4
+ const defs=require("./defs.js")
5
+ const color={green:"#5ee432",yellow:"#fffa50",orange:"#f7aa38",red:"#ef4655"}
6
+
7
+ const svcTextLine=(metricLabel,value)=>{
8
+ return [{action:"style",children:[".svcTextLine {font: italic 13px sans-serif}"]},
9
+ {action:"text",height:10,class:"svcTextLine",children:[metricLabel+": "+value]}
10
+ ]
11
+ }
12
+ const calculatePositionVertically=(a,offset=0)=>{
13
+ const l=a.length
14
+ if(!l) return
15
+ let aPrevious=a[0]
16
+ if(aPrevious.transform) aPrevious={action:'g',height:aPrevious.height,children:[aPrevious]}
17
+ aPrevious.transform={translate:{y:offset}}
18
+ for(let i=1;i<l;i++){
19
+ let aCurrent=a[i]
20
+ if(aCurrent.transform) aCurrent={action:'g',height:aCurrent.height,children:[aCurrent]}
21
+ if(!aCurrent) throw Error("action is null for "+i +" in "+JSON.stringify(a))
22
+ if(!aPrevious.height) console.error("calculatePositionVertically no height")
23
+ aCurrent.transform={translate:{y:aPrevious.transform.translate.y+aPrevious.height}}
24
+ aPrevious=aCurrent
25
+ }
26
+ return a
27
+ }
28
+
29
+ const moveTransform = (x,y)=>[[1,0,x],[0,1,y]]
30
+ const boundValue=(v,max=100,min=0)=>Math.min(Math.max(v, min), max)
31
+ const twoPi=2 * Math.PI
32
+ const getCircumference=(radius)=>radius*twoPi
33
+ const getAcLength = (radius,angle)=> getCircumference(radius) * (angle / 360)
34
+ const getArcDasharray=(radius,angle)=>{
35
+ const circumference = getCircumference(innerRadius)
36
+ const arc = circumference * (angle / 360)
37
+ return {strokeDasharray: ""+arc+" "+circumference}
38
+ }
39
+ const getElementWidth=(e)=>parseInt(window.getComputedStyle(e, null).getPropertyValue("width"))
40
+
41
+
42
+ const geBarChart=(dataPoint=[],size,x,y)=>{
43
+ const min=Math.min(...dataPoint)
44
+ const max=Math.min(...dataPoint)
45
+ const range=max-min
46
+ const norm=range/size
47
+ return dataPoint.reduce((p,c,i)=>{
48
+ const delta=(c-min)/norm
49
+ x+=c
50
+ p.push({action:"rect",x:x,y:y,width:w,height:h,fill:fill[0]})
51
+ return p
52
+ },[])
53
+ }
54
+
55
+ const DialGauge = require("./DialGauge.js")
56
+ //const dialGauge=new DialGauge()
57
+ const Chart = require("../lib/Chart.js")
58
+
59
+ module.exports={
60
+ barGauge:null,
61
+ Chart:Chart,
62
+ DialGauge:DialGauge,
63
+ calculatePositionVertically:calculatePositionVertically
64
+ }
package/package.json CHANGED
@@ -1,12 +1,17 @@
1
1
  {
2
2
  "name": "node-red-contrib-prib-functions",
3
- "version": "0.18.0",
3
+ "version": "0.20.4",
4
4
  "description": "Node-RED added node functions.",
5
5
  "dependencies": {
6
- "avsc": "^5.6.1",
7
- "fast-xml-parser": "^3.19.0",
8
- "node-red-contrib-logger": "^0.0.6",
9
- "xlsx": "^0.17.0"
6
+ "avsc": ">=5.7.7",
7
+ "compressiontool": "*",
8
+ "fast-xml-parser": "^4.2.5",
9
+ "node": ">=0.6.13",
10
+ "node-red-contrib-logger": "latest",
11
+ "node-red-contrib-noderedbase": ">=0.0.16",
12
+ "node-red-contrib-prib-functions": "file:",
13
+ "npm": "^10.9.0",
14
+ "xlsx": "*"
10
15
  },
11
16
  "devDependencies": {
12
17
  "@node-red/runtime": ">=1.2.8",
@@ -14,11 +19,15 @@
14
19
  "bcrypt": "^5.0.1",
15
20
  "bl": "^5.0.0",
16
21
  "mocha": "^9.2.2",
17
- "node-red": "^2.2.2",
18
- "node-red-node-test-helper": "^0.2.7"
22
+ "node-red": "^3.0.2",
23
+ "node-red-node-test-helper": "^0.3.0"
19
24
  },
20
25
  "scripts": {
21
- "test": "mocha \"test/matrix/**/*.js\""
26
+ "test": "mocha \"test/dataAnalysisE*.js\"",
27
+ "test2": "mocha \"test/transformNum*.js\"",
28
+ "test00": "mocha \"test/00*.js\"",
29
+ "test04": "mocha \"test/04*.js\"",
30
+ "startNodeRed": "node-red --userDir ./test/data --setting ./test/data/settings.js ./test/data/flow.json --title '***test nodered***'"
22
31
  },
23
32
  "repository": {
24
33
  "type": "git",
@@ -36,14 +45,20 @@
36
45
  "backward substitution",
37
46
  "compare",
38
47
  "Complement Minor",
48
+ "compression",
39
49
  "CMA",
40
50
  "cumulative",
41
51
  "Cumulative Moving Average",
42
52
  "data",
43
53
  "data analysis",
54
+ "decompression",
55
+ "deflate",
44
56
  "delta",
45
57
  "determinant",
46
58
  "distance",
59
+ "difference",
60
+ "seasonal difference",
61
+ "second order difference",
47
62
  "euclidian distance",
48
63
  "EMA",
49
64
  "EWMA",
@@ -53,9 +68,11 @@
53
68
  "gauss jordan",
54
69
  "Gauss Jordan Inverse",
55
70
  "gaussian elimination",
71
+ "gzip",
56
72
  "host available",
57
73
  "host status",
58
74
  "identity",
75
+ "inflate",
59
76
  "injector",
60
77
  "inverse",
61
78
  "inverse matrix",
@@ -66,6 +83,7 @@
66
83
  "matrix",
67
84
  "maximum",
68
85
  "mean",
86
+ "memory",
69
87
  "median",
70
88
  "minimun",
71
89
  "model",
@@ -92,11 +110,13 @@
92
110
  "stddev",
93
111
  "spawn",
94
112
  "spawn process",
113
+ "system",
95
114
  "testing",
96
115
  "test",
97
116
  "translate",
98
117
  "transform",
99
118
  "transpose",
119
+ "unzip",
100
120
  "variance",
101
121
  "weighted",
102
122
  "Weighted Moving Average",
@@ -106,9 +126,11 @@
106
126
  "xcel",
107
127
  "xml",
108
128
  "XML",
129
+ "zip",
109
130
  "Z-score"
110
131
  ],
111
132
  "node-red": {
133
+ "version": ">=2.0.0",
112
134
  "nodes": {
113
135
  "append": "append/append.js",
114
136
  "dataAnalysis": "dataAnalysis/dataAnalysis.js",
@@ -117,6 +139,7 @@
117
139
  "load-injector": "testing/load-injector.js",
118
140
  "matrix": "matrix/matrixNode.js",
119
141
  "monitorflow": "monitor/monitorflow.js",
142
+ "monitorSystem": "monitor/monitorSystem.js",
120
143
  "os": "nodejs/os.js",
121
144
  "spawnProcess": "spawnProcess/spawnProcess.js",
122
145
  "test": "testing/test.js",
@@ -0,0 +1,94 @@
1
+ const assert=require('assert');
2
+ const should=require("should");
3
+ require("../lib/objectExtensions");
4
+
5
+ describe('/lib/objectExtensions array ', function() {
6
+ it("array find sorted empty set", function(done) {
7
+ assert.strictEqual([].findSorted("1"),-0)
8
+ done()
9
+ })
10
+ it("array find sorted [1] for 1", function(done) {
11
+ assert.strictEqual(["0"].findSorted("0"),0)
12
+ done()
13
+ })
14
+ it("array find sorted [1] for 2", function(done) {
15
+ assert.strictEqual(["0"].findSorted("1"),-1)
16
+ done()
17
+ })
18
+ it("array find sorted matches", function(done) {
19
+ assert.strictEqual(["0","1"].findSorted("1"),1)
20
+ assert.strictEqual(["0","1","2"].findSorted("1"),1)
21
+ assert.strictEqual(["0","1","2"].findSorted("2"),2)
22
+ done()
23
+ })
24
+ it("array find sorted misses", function(done) {
25
+ assert.strictEqual(["1","3","5"].findSorted("0"),-0)
26
+ assert.strictEqual(["1","3","5"].findSorted("2"),-1)
27
+ assert.strictEqual(["1","3","5"].findSorted("4"),-2)
28
+ assert.strictEqual(["1","3","5"].findSorted("6"),-3)
29
+ done()
30
+ })
31
+ it("array add sorted empty set", function(done) {
32
+ const result=[]
33
+ result.addSorted("1")
34
+ console.log(result)
35
+ assert.strictEqual([].addSorted("1"),0)
36
+ done()
37
+ })
38
+ it("array add sorted [1] for 1", function(done) {
39
+ assert.strictEqual(["1"].addSorted("1"),-0)
40
+ done()
41
+ })
42
+ it("array add sorted [1] for 2", function(done) {
43
+ assert.strictEqual(["1"].addSorted("2"),1)
44
+ done()
45
+ })
46
+ it("array add sorted matches", function(done) {
47
+ assert.strictEqual(["1","2"].addSorted("2"),1)
48
+ assert.strictEqual(["1","2","3"].addSorted("2"),1)
49
+ assert.strictEqual(["1","2","3"].addSorted("3"),2)
50
+ done()
51
+ })
52
+ it("array add sorted misses", function(done) {
53
+ const list=["1","3","5"]
54
+ assert.strictEqual(list.addSorted("0"),0)
55
+ assert.deepStrictEqual(list,["0","1","3","5"])
56
+ assert.strictEqual(list.addSorted("2"),2)
57
+ assert.deepStrictEqual(list,["0","1","2","3","5"])
58
+ assert.strictEqual(["0","1","2","3","5"].addSorted("4"),4)
59
+ assert.strictEqual(list.addSorted("4"),4)
60
+ assert.deepStrictEqual(list,['0',"1","2","3","4","5"])
61
+ done()
62
+ })
63
+ it("array add sorted misses at lend", function(done) {
64
+ assert.strictEqual(["1","3","5"].addSorted("6"),3)
65
+ done()
66
+ })
67
+ })
68
+ describe('/lib/objectExtensions object', function() {
69
+ it("addList", function(done) {
70
+ const list={}
71
+ list.addList("1",1)
72
+ assert.deepStrictEqual(list,{"1":[1]})
73
+ list.addList("1",2)
74
+ assert.deepStrictEqual(list,{"1":[1,2]})
75
+ list.addList("3",3)
76
+ assert.deepStrictEqual(list,{"1":[1,2],"3":[3]})
77
+ list.addList("2",4)
78
+ assert.deepStrictEqual(list,{"1":[1,2],"3":[3],"2":[4]})
79
+ done()
80
+ })
81
+ })
82
+ describe('/lib/objectExtensions csvLine', function() {
83
+ it("standard", function(done) {
84
+ assert.deepStrictEqual("".csvLine(),[])
85
+ assert.deepStrictEqual("1".csvLine(),[1])
86
+ assert.deepStrictEqual("1,2".csvLine(),[1,2])
87
+ assert.deepStrictEqual("1,,2".csvLine(),[1,null,2])
88
+ assert.deepStrictEqual("first,,last".csvLine(),["first",null,"last"])
89
+ assert.deepStrictEqual("\"first\",,\"last\"".csvLine(),["first",null,"last"])
90
+ assert.deepStrictEqual("\"first\",\"abc - 123\",\"~!@#$%^&*()_+-=`{}[]:;'|\\ <,>.?/\",\"last\"".csvLine()
91
+ ,["first","abc - 123","~!@#$%^&*()_+-=`{}[]:;'|\\ <,>.?/","last"])
92
+ done()
93
+ })
94
+ })
@@ -0,0 +1,88 @@
1
+ const assert=require('assert');
2
+ const should=require("should");
3
+ const helper=require("node-red-node-test-helper");
4
+ const storageDefinition=require("../nodes/storageDefinition.js");
5
+ const storageRead = require('../nodes/storageRead.js');
6
+
7
+ helper.init(require.resolve('node-red'));
8
+
9
+ function getAndTestNodeProperties(o) {
10
+ const n = helper.getNode(o.id);
11
+ for(let p in o) n.should.have.property(p, o[p]);
12
+ return n;
13
+ }
14
+
15
+ const blockStorage={
16
+ id : "blockStorage",
17
+ type : "Storage Definition",
18
+ name : "Block Storage",
19
+ action: "blockStorage",
20
+ sourceProperty:"blockStorageFile",
21
+ blockSize:4096
22
+ };
23
+
24
+ const StorageReadBlock={
25
+ id : "StorageReadBlockid",
26
+ type : "Storage Read",
27
+ name : "Block Storage",
28
+ target:"payload",
29
+ "target-type":"msg",
30
+ key:"topic"
31
+ };
32
+
33
+ function testFlow(done,node,data,result) {
34
+ const flow = [
35
+ Object.assign(node,{wires : [ [ "outHelper" ],["errorHelper"] ]}),
36
+ {id :"outHelper", type : "helper"},
37
+ {id :"errorHelper", type : "helper"}
38
+ ];
39
+ helper.load(storageDefinition, flow, function() {
40
+ const n=getAndTestNodeProperties(node);
41
+ const outHelper = helper.getNode("outHelper");
42
+ const errorHelper = helper.getNode("errorHelper");
43
+ outHelper.on("input", function(msg) {
44
+ console.log("outHelper "+JSON.stringify(msg.payload));
45
+ if(JSON.stringify(msg.payload)==JSON.stringify(result)) {
46
+ done();
47
+ } else {
48
+ console.log("mismatch expected: "+JSON.stringify(result) +" returned: "+JSON.stringify(msg.payload));
49
+ done("mismatch");
50
+ }
51
+ });
52
+ errorHelper.on("input", function(msg) {
53
+ console.log("errorHelper "+JSON.stringify(msg));
54
+ done("error check log output");
55
+ });
56
+ n.receive({
57
+ topic:"test",
58
+ payload : data
59
+ });
60
+ });
61
+ }
62
+
63
+ describe('Storage Defintion', function() {
64
+ beforeEach(function(done) {
65
+ helper.startServer(done);
66
+ });
67
+ afterEach(function(done) {
68
+ helper.unload();
69
+ helper.stopServer(done);
70
+ });
71
+ it("load config", function(done) {
72
+ helper.load(storageDefinition,[], function() {
73
+ const n=getAndTestNodeProperties(storageDefinition);
74
+ });
75
+ done();
76
+ });
77
+ it("load read", function(done) {
78
+ helper.load(storageDefinition,storageRead,[], function() {
79
+ const n=getAndTestNodeProperties(storageDefinition);
80
+ });
81
+ done();
82
+ });
83
+
84
+ it('read 1', function(done) {
85
+ const msg={topic:1}
86
+ testFlow(done,storageDefinition,msg,msg);
87
+ });
88
+ });
@@ -0,0 +1,33 @@
1
+ //const assert=require('assert');
2
+ const assert = require('node:assert/strict');
3
+ const Table=require("../lib/Table");
4
+ describe('/lib/Table ', function() {
5
+ const data=[[11,12,"one"],[1,2,"one"],[21,22,"two"],[21,22,"three"]]
6
+ it("add column", function(done) {
7
+ const table=new Table({data:data})
8
+ assert.throws(()=>table.addColumn({type:"notvalid"},/^no column name$/))
9
+ // table.addColumn({name:"col1"})
10
+ assert.throws(()=>table.addColumn({name:"col1"}),/^Error: invalid type: null.*$/)
11
+ assert.throws(()=>table.addColumn({name:"col1",type:"notvalid"}),/^Error: invalid type: notvalid.*$/)
12
+ done()
13
+ })
14
+ it("columnar", function(done) {
15
+ const table=new Table({data:data})
16
+ .addColumn({name:"c1",type:"int"})
17
+ .addColumn({name:"c2",type:"real"})
18
+ .addColumn({name:"c3",type:"string"})
19
+ .buildColumnIndices()
20
+ done()
21
+ })
22
+ })
23
+
24
+ const GraphDB=require("../lib/GraphDB");
25
+ describe('/lib/GraphDB ', function() {
26
+ it("add vertex", function(done) {
27
+ const nodes=[{},{}]
28
+ const graphDB=new GraphDB()
29
+ graphDB.addVertex(nodes[0])
30
+ graphDB.addEdge(nodes[0],nodes[1])
31
+ done()
32
+ })
33
+ })