@machinemetrics/io-adapter-lib 2.32.0

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 (264) hide show
  1. package/.circleci/config.yml +141 -0
  2. package/.eslintrc.json +36 -0
  3. package/.gitattributes +12 -0
  4. package/CHANGELOG.md +544 -0
  5. package/README.md +2 -0
  6. package/index.js +17 -0
  7. package/lib/config/adapterConfig.js +535 -0
  8. package/lib/config/common/allowDenyList.js +58 -0
  9. package/lib/config/common/jsonPath.js +44 -0
  10. package/lib/config/common/labjackU3T4Common.js +227 -0
  11. package/lib/config/common/validations.js +142 -0
  12. package/lib/config/configError.js +32 -0
  13. package/lib/config/device/adam-6052Config.js +103 -0
  14. package/lib/config/device/brotherHTTPConfig.js +215 -0
  15. package/lib/config/device/ethernetIPConfig.js +191 -0
  16. package/lib/config/device/ifmIotConfig.js +245 -0
  17. package/lib/config/device/jsonHttpConfig.js +76 -0
  18. package/lib/config/device/labjackT4Config.js +39 -0
  19. package/lib/config/device/labjackT7Config.js +192 -0
  20. package/lib/config/device/labjackU3Config.js +32 -0
  21. package/lib/config/device/modbusTcpConfig.js +336 -0
  22. package/lib/config/device/mqttBaseConfig.js +70 -0
  23. package/lib/config/device/mqttConfig.js +113 -0
  24. package/lib/config/device/mqttLincolnConfig.js +62 -0
  25. package/lib/config/device/mtconnectAdapterConfig.js +42 -0
  26. package/lib/config/device/mtconnectBaseConfig.js +136 -0
  27. package/lib/config/device/mtconnectConfig.js +52 -0
  28. package/lib/config/device/mtconnectHaasConfig.js +15 -0
  29. package/lib/config/device/nullConfig.js +81 -0
  30. package/lib/config/device/opcuaConfig.js +205 -0
  31. package/lib/config/device/pcccConfig.js +88 -0
  32. package/lib/config/engineConfigV1.js +382 -0
  33. package/lib/config/engineConfigV2.js +106 -0
  34. package/lib/config/generator/counterGenConfig.js +15 -0
  35. package/lib/config/generator/cronGenConfig.js +33 -0
  36. package/lib/config/generator/dateTimeGenConfig.js +33 -0
  37. package/lib/config/index.js +339 -0
  38. package/lib/config/transformConfigUtil.js +296 -0
  39. package/lib/engine/dataOutput.js +357 -0
  40. package/lib/engine/deviceOutput.js +186 -0
  41. package/lib/engine/engineV1.js +480 -0
  42. package/lib/engine/engineV2.js +719 -0
  43. package/lib/engine/index.js +34 -0
  44. package/lib/engine/transformBuilderV1.js +111 -0
  45. package/lib/engine/transformBuilderV2.js +74 -0
  46. package/lib/expressionService.js +330 -0
  47. package/lib/math.js +142 -0
  48. package/lib/transform/accumulate.js +98 -0
  49. package/lib/transform/average.js +56 -0
  50. package/lib/transform/debounce.js +152 -0
  51. package/lib/transform/downsample.js +69 -0
  52. package/lib/transform/edge.js +34 -0
  53. package/lib/transform/expression.js +91 -0
  54. package/lib/transform/fallingEdge.js +70 -0
  55. package/lib/transform/fromBuffer.js +89 -0
  56. package/lib/transform/hash.js +41 -0
  57. package/lib/transform/ignoreValue.js +118 -0
  58. package/lib/transform/index.js +93 -0
  59. package/lib/transform/invert.js +25 -0
  60. package/lib/transform/latch.js +99 -0
  61. package/lib/transform/latchValue.js +115 -0
  62. package/lib/transform/logicAnd.js +67 -0
  63. package/lib/transform/logicOr.js +67 -0
  64. package/lib/transform/map.js +115 -0
  65. package/lib/transform/max.js +57 -0
  66. package/lib/transform/maxLength.js +39 -0
  67. package/lib/transform/min.js +57 -0
  68. package/lib/transform/minDelta.js +40 -0
  69. package/lib/transform/offDelay.js +89 -0
  70. package/lib/transform/onDelay.js +89 -0
  71. package/lib/transform/patternEscape.js +24 -0
  72. package/lib/transform/patternMatch.js +194 -0
  73. package/lib/transform/patternReplace.js +170 -0
  74. package/lib/transform/patternTest.js +85 -0
  75. package/lib/transform/rateOfChange.js +56 -0
  76. package/lib/transform/reject.js +115 -0
  77. package/lib/transform/resample.js +96 -0
  78. package/lib/transform/risingEdge.js +90 -0
  79. package/lib/transform/risingEdgeCounter.js +179 -0
  80. package/lib/transform/sampleInterval.js +12 -0
  81. package/lib/transform/source.js +116 -0
  82. package/lib/transform/state.js +201 -0
  83. package/lib/transform/threshold.js +52 -0
  84. package/lib/transform/toBuffer.js +159 -0
  85. package/lib/transform/toggle.js +118 -0
  86. package/lib/transform/transformState.js +193 -0
  87. package/lib/transform/trim.js +27 -0
  88. package/lib/transform/util/chainSource.js +96 -0
  89. package/lib/transform/util/ringBuffer.js +34 -0
  90. package/lib/transform/valueChange.js +34 -0
  91. package/lib/transform/valueDecrease.js +38 -0
  92. package/lib/transform/valueIncrease.js +38 -0
  93. package/lib/transform/valueIncreaseDiff.js +66 -0
  94. package/lib/transform/whenUnavailable.js +73 -0
  95. package/lib/transform/windowCount.js +86 -0
  96. package/lib/util/fileUtil.js +44 -0
  97. package/package.json +38 -0
  98. package/test/.eslintrc.json +15 -0
  99. package/test/chainedTransform.test.js +88 -0
  100. package/test/conditions.test.js +118 -0
  101. package/test/config/ab-pccc.test.js +41 -0
  102. package/test/config/adam-6052.test.js +16 -0
  103. package/test/config/adapter.test.js +109 -0
  104. package/test/config/brother-http.test.js +19 -0
  105. package/test/config/ethernet-ip.test.js +19 -0
  106. package/test/config/ifm-iot.test.js +20 -0
  107. package/test/config/json-http.test.js +47 -0
  108. package/test/config/labjack-t4.test.js +78 -0
  109. package/test/config/labjack-t7.test.js +18 -0
  110. package/test/config/labjack-u3.test.js +17 -0
  111. package/test/config/modbusTcp.test.js +87 -0
  112. package/test/config/mqtt.test.js +19 -0
  113. package/test/config/mqttLincoln.test.js +29 -0
  114. package/test/config/mtconnect.test.js +63 -0
  115. package/test/config/mtconnectAdapter.test.js +124 -0
  116. package/test/config/mtconnectHaas.test.js +15 -0
  117. package/test/config/null.test.js +16 -0
  118. package/test/config/opcua.test.js +97 -0
  119. package/test/config-tests.js +102 -0
  120. package/test/configFiles/conditions.yml +37 -0
  121. package/test/configFiles/data-items-legacy.yml +24 -0
  122. package/test/configFiles/data-items-shorthand.yml +14 -0
  123. package/test/configFiles/data-items.yml +12 -0
  124. package/test/configFiles/device/ab-pccc-default.yml +3 -0
  125. package/test/configFiles/device/ab-pccc-full.yml +13 -0
  126. package/test/configFiles/device/adam-6052-default.yml +2 -0
  127. package/test/configFiles/device/brother-http-default.yml +3 -0
  128. package/test/configFiles/device/ethernet-ip-default.yml +2 -0
  129. package/test/configFiles/device/ifm-iot-default.yml +2 -0
  130. package/test/configFiles/device/json-http-bad-prop.yml +13 -0
  131. package/test/configFiles/device/json-http-bad-prop2.yml +13 -0
  132. package/test/configFiles/device/json-http-default.yml +3 -0
  133. package/test/configFiles/device/json-http-std.yml +13 -0
  134. package/test/configFiles/device/labjack-t4-condition-exprs.yaml +46 -0
  135. package/test/configFiles/device/labjack-t4-default.yml +3 -0
  136. package/test/configFiles/device/labjack-t4-pins-alt.yaml +41 -0
  137. package/test/configFiles/device/labjack-t4-pins.yaml +40 -0
  138. package/test/configFiles/device/labjack-t4-v1.yaml +29 -0
  139. package/test/configFiles/device/labjack-t7-default.yml +2 -0
  140. package/test/configFiles/device/labjack-u3-default.yml +2 -0
  141. package/test/configFiles/device/modbus-partial.yml +4 -0
  142. package/test/configFiles/device/modbus-std-extended.yaml +23 -0
  143. package/test/configFiles/device/modbus-std.yaml +34 -0
  144. package/test/configFiles/device/modbus-tcp-default.yml +3 -0
  145. package/test/configFiles/device/mqtt-default.yml +2 -0
  146. package/test/configFiles/device/mqtt-lincoln-default.yml +3 -0
  147. package/test/configFiles/device/mqtt-lincoln-full.yml +7 -0
  148. package/test/configFiles/device/mtconnect-adapter-default.yml +3 -0
  149. package/test/configFiles/device/mtconnect-adapter-keys.yaml +18 -0
  150. package/test/configFiles/device/mtconnect-complex-keys.yaml +17 -0
  151. package/test/configFiles/device/mtconnect-default.yml +3 -0
  152. package/test/configFiles/device/mtconnect-duplicate-allow-keys.yaml +10 -0
  153. package/test/configFiles/device/mtconnect-duplicate-declare-keys.yaml +8 -0
  154. package/test/configFiles/device/mtconnect-duplicate-deny-keys.yaml +10 -0
  155. package/test/configFiles/device/mtconnect-haas-default.yml +3 -0
  156. package/test/configFiles/device/mtconnect-std.yaml +18 -0
  157. package/test/configFiles/device/null-default.yml +1 -0
  158. package/test/configFiles/device/opcua-bad-tag.yml +18 -0
  159. package/test/configFiles/device/opcua-bad-tag2.yml +18 -0
  160. package/test/configFiles/device/opcua-default.yml +3 -0
  161. package/test/configFiles/device/opcua-std.yml +18 -0
  162. package/test/configFiles/dump-test.yml +11 -0
  163. package/test/configFiles/expressionCond.yml +46 -0
  164. package/test/configFiles/min-config-t4.yaml +4 -0
  165. package/test/configFiles/min-config-u3.yaml +3 -0
  166. package/test/configFiles/missing-device.yaml +2 -0
  167. package/test/configFiles/parse-error1.yml +9 -0
  168. package/test/configFiles/parse-error2.yml +9 -0
  169. package/test/configFiles/repro/buffer-convert-repro.yml +15 -0
  170. package/test/configFiles/repro/chained-delay-timing-repro.yml +13 -0
  171. package/test/configFiles/repro/count-init-repro.yml +45 -0
  172. package/test/configFiles/repro/cycle-break-repro.yml +44 -0
  173. package/test/configFiles/repro/debounce-repro.yml +46 -0
  174. package/test/configFiles/repro/diff-count-repro.yml +34 -0
  175. package/test/configFiles/repro/engine-hang-repro.yml +9 -0
  176. package/test/configFiles/repro/latch-apm-repro.yml +26 -0
  177. package/test/configFiles/repro/lockout-count-repro.yml +33 -0
  178. package/test/configFiles/repro/program-extract-repro.yml +38 -0
  179. package/test/configFiles/repro/state-latch-repro.yml +47 -0
  180. package/test/configFiles/repro/ternary-repro.yml +26 -0
  181. package/test/configFiles/transform/debounce.yml +12 -0
  182. package/test/configFiles/transform/expression.yml +34 -0
  183. package/test/configFiles/transform/ignoreValue.yml +31 -0
  184. package/test/configFiles/transform/latch.yml +11 -0
  185. package/test/configFiles/transform/latchValue.yml +31 -0
  186. package/test/configFiles/transform/logicAnd.yml +14 -0
  187. package/test/configFiles/transform/logicOr.yml +14 -0
  188. package/test/configFiles/transform/map.yml +19 -0
  189. package/test/configFiles/transform/maxLength.yml +13 -0
  190. package/test/configFiles/transform/offDelay.yml +12 -0
  191. package/test/configFiles/transform/pattern-escape.yml +10 -0
  192. package/test/configFiles/transform/pattern-match.yml +57 -0
  193. package/test/configFiles/transform/pattern-replace.yml +34 -0
  194. package/test/configFiles/transform/pattern-test.yml +25 -0
  195. package/test/configFiles/transform/reject.yml +24 -0
  196. package/test/configFiles/transform/risingEdgeCounter.yml +36 -0
  197. package/test/configFiles/transform/source.yml +20 -0
  198. package/test/configFiles/transform/state.yml +56 -0
  199. package/test/configFiles/transform/toggle.yml +19 -0
  200. package/test/configFiles/transform/whenUnavailable.yml +19 -0
  201. package/test/dataFiles/noisy-pulse.txt +11330 -0
  202. package/test/dataItems.test.js +140 -0
  203. package/test/engine-v1-tests.js +418 -0
  204. package/test/engine-v2-tests.js +284 -0
  205. package/test/expression-tests.js +171 -0
  206. package/test/expressionService.test.js +154 -0
  207. package/test/expressionServiceCondition.test.js +130 -0
  208. package/test/repro/buffer-convert-repro.test.js +38 -0
  209. package/test/repro/chained-delay-timing-repro.test.js +34 -0
  210. package/test/repro/count-init-repro.test.js +46 -0
  211. package/test/repro/cylce-break-repro.test.js +57 -0
  212. package/test/repro/debounce-repro.test.js +65 -0
  213. package/test/repro/diff-count-repro.test.js +79 -0
  214. package/test/repro/engine-hang-repro.test.js +38 -0
  215. package/test/repro/latch-apm-repro.test.js +119 -0
  216. package/test/repro/lockout-count-repro.test.js +84 -0
  217. package/test/repro/program-extract-repro.test.js +40 -0
  218. package/test/repro/state-latch-repro.test.js +63 -0
  219. package/test/repro/ternary-repro.test.js +43 -0
  220. package/test/transform/accumulte.test.js +18 -0
  221. package/test/transform/average.test.js +22 -0
  222. package/test/transform/debounce.test.js +70 -0
  223. package/test/transform/downsample.test.js +30 -0
  224. package/test/transform/edge.test.js +27 -0
  225. package/test/transform/expression.test.js +189 -0
  226. package/test/transform/fallingEdge.test.js +59 -0
  227. package/test/transform/fromBuffer.test.js +60 -0
  228. package/test/transform/hash.test.js +34 -0
  229. package/test/transform/ignoreValue.test.js +123 -0
  230. package/test/transform/invert.test.js +26 -0
  231. package/test/transform/latch.test.js +33 -0
  232. package/test/transform/latchValue.test.js +126 -0
  233. package/test/transform/logicAnd.test.js +80 -0
  234. package/test/transform/logicOr.test.js +80 -0
  235. package/test/transform/map.test.js +42 -0
  236. package/test/transform/max.test.js +30 -0
  237. package/test/transform/maxLength.test.js +32 -0
  238. package/test/transform/min.test.js +30 -0
  239. package/test/transform/minDelta.test.js +14 -0
  240. package/test/transform/offDelay.test.js +123 -0
  241. package/test/transform/onDelay.test.js +105 -0
  242. package/test/transform/patternEscape.test.js +18 -0
  243. package/test/transform/patternMatch.test.js +177 -0
  244. package/test/transform/patternReplace.test.js +95 -0
  245. package/test/transform/patternTest.test.js +105 -0
  246. package/test/transform/rateOfChange.test.js +34 -0
  247. package/test/transform/reject.test.js +56 -0
  248. package/test/transform/resample.test.js +193 -0
  249. package/test/transform/risingEdge.test.js +60 -0
  250. package/test/transform/risingEdgeCounter.test.js +227 -0
  251. package/test/transform/sampleInterval.test.js +22 -0
  252. package/test/transform/source.test.js +137 -0
  253. package/test/transform/state.test.js +248 -0
  254. package/test/transform/threshold.test.js +78 -0
  255. package/test/transform/toBuffer.test.js +60 -0
  256. package/test/transform/toggle.test.js +92 -0
  257. package/test/transform/trim.test.js +30 -0
  258. package/test/transform/valueChange.test.js +14 -0
  259. package/test/transform/valueDecrease.test.js +32 -0
  260. package/test/transform/valueIncrease.test.js +32 -0
  261. package/test/transform/valueIncreaseDiff.test.js +32 -0
  262. package/test/transform/whenUnavailable.test.js +93 -0
  263. package/test/transform/windowCount.test.js +26 -0
  264. package/test/util/testUtils.js +405 -0
@@ -0,0 +1,30 @@
1
+ 'use strict';
2
+
3
+ const Min = require('../../lib/transform').min;
4
+ const testUtils = require('../util/testUtils');
5
+
6
+ describe('min transform tests', function () {
7
+ it('min regular 1', function () {
8
+ const filter = new Min(1);
9
+ testUtils.attachTransformValidator(filter);
10
+
11
+ filter.testAnalog([1, 3, 5, 7, 9, 2, 4, 6, 8, 0], 1);
12
+ filter.valdAnalog([1, 3, 5, 7, 9, 2, 4, 6, 8, 0], 1);
13
+ });
14
+
15
+ it('min regular 2', function () {
16
+ const filter = new Min(2);
17
+ testUtils.attachTransformValidator(filter);
18
+
19
+ filter.testAnalog([1, 3, 5, 7, 9, 2, 4, 6, 8, 0], 1);
20
+ filter.valdAnalog([0, 1, 3, 5, 7, 2, 2, 4, 6, 0], 1);
21
+ });
22
+
23
+ it('min regular 5', function () {
24
+ const filter = new Min(5);
25
+ testUtils.attachTransformValidator(filter);
26
+
27
+ filter.testAnalog([1, 3, 5, 7, 9, 2, 4, 6, 8, 0], 1);
28
+ filter.valdAnalog([0, 0, 0, 0, 1, 2, 2, 2, 2, 0], 1);
29
+ });
30
+ });
@@ -0,0 +1,14 @@
1
+ 'use strict';
2
+
3
+ const MinDelta = require('../../lib/transform').minDelta;
4
+ const testUtils = require('../util/testUtils');
5
+
6
+ describe('min-delta transform tests', function () {
7
+ it('min-delta regular', function () {
8
+ const filter = new MinDelta(4);
9
+ testUtils.attachTransformValidator(filter);
10
+
11
+ filter.testAnalog([1, 3, 5, 7, 9, 2, 4, 6, 8, 0], 1);
12
+ filter.valdAnalog([0, 0, 5, 5, 9, 2, 2, 6, 6, 0], 1);
13
+ });
14
+ });
@@ -0,0 +1,123 @@
1
+ 'use strict';
2
+
3
+ const expect = require('chai').expect;
4
+ const Source = require('../../lib/transform').source;
5
+ const OffDelay = require('../../lib/transform').offDelay;
6
+ const EngineV2 = require('../../lib/engine/engineV2');
7
+ const Builder = require('../../lib/engine/transformBuilderV2');
8
+ const ExpressionService = require('../../lib/expressionService');
9
+ const testUtils = require('../util/testUtils');
10
+
11
+ describe('off-delay transform tests', function () {
12
+ it('off-delay regular', function () {
13
+ const filter = new OffDelay(3);
14
+ testUtils.attachTransformValidator(filter);
15
+
16
+ filter.testDigital('__^^__^^^^____^_^^^^^___^^____|___', 1);
17
+ filter.valdDigital('__^^^^^^^^^^^_^^^^^^^^^^|^^^^_^^^_', 1);
18
+ });
19
+
20
+ it('off-delay irregular', function () {
21
+ // Without an engine to honor penching change times, off changes can be missed in gaps
22
+ const filter = new OffDelay(3);
23
+ testUtils.attachTransformValidator(filter);
24
+
25
+ filter.test([
26
+ [true, 2], [false, 4], [true, 6], [false, 10], [true, 14], [false, 15], [true, 16], [false, 21],
27
+ ]);
28
+ filter.validate([
29
+ [true, 2], [true, 4], [true, 6], [true, 10], [true, 14], [true, 15], [true, 16], [true, 21],
30
+ ]);
31
+ });
32
+
33
+ it('supports pending change', function () {
34
+ const filter = new OffDelay(3);
35
+ expect(filter.supportsPendingChanges()).to.eq(true);
36
+ expect(filter.nextPendingChange()).to.eq(null);
37
+
38
+ const context = { sourceType: 'test', trigger: 'test' };
39
+
40
+ filter.update(context, true, 3);
41
+ filter.update(context, false, 4);
42
+ expect(filter.nextPendingChange()).to.eq(7);
43
+
44
+ filter.update(context, false, 5);
45
+ expect(filter.nextPendingChange()).to.eq(7);
46
+ filter.update(context, true, 6);
47
+ expect(filter.nextPendingChange()).to.eq(null);
48
+ filter.update(context, false, 7);
49
+ expect(filter.nextPendingChange()).to.eq(10);
50
+ filter.update(context, false, 11);
51
+ expect(filter.nextPendingChange()).to.eq(null);
52
+
53
+ filter.update(context, true, 12);
54
+ filter.update(context, false, 15);
55
+ expect(filter.nextPendingChange()).to.eq(18);
56
+ filter.update(context, false, 18);
57
+ expect(filter.nextPendingChange()).to.eq(null);
58
+
59
+ filter.update(context, true, 20);
60
+ filter.update(context, false, 22);
61
+ filter.setUnavailable(context, 23);
62
+ expect(filter.nextPendingChange()).to.eq(null);
63
+ });
64
+ });
65
+
66
+ describe('off-delay transform engine tests', function () {
67
+ it('off-delay irregular', function () {
68
+ const exprsvc = new ExpressionService();
69
+ const engine = new EngineV2({ expressionService: exprsvc });
70
+
71
+ exprsvc.addName({ name: 'pin-1', defaultValue: 0, channel: 'device' });
72
+ exprsvc.addExpression({ expression: 'pin-1', path: 'test1' });
73
+
74
+ const filter = new Source({
75
+ engine,
76
+ path: 'test1',
77
+ baseTransform: true,
78
+ args: {
79
+ expression: 'pin-1',
80
+ },
81
+ }).chain(new OffDelay(3));
82
+ engine.addVariable('res', filter);
83
+
84
+ testUtils.attachEngineTransformValidator(engine, filter);
85
+
86
+ engine.test([
87
+ [true, 2], [false, 4], [true, 6], [false, 10], [true, 14], [false, 15], [true, 16], [false, 21],
88
+ ]);
89
+ engine.validateFilter([
90
+ [true, 2], [true, 4], [true, 6], [true, 10], [false, 13], [true, 14], [true, 15], [true, 16], [true, 21],
91
+ ]);
92
+ engine.validateEngine('res', [
93
+ [true, 2], [false, 13], [true, 14],
94
+ ]);
95
+ });
96
+ });
97
+
98
+ describe('off-delay transform full engine tests', function () {
99
+ let config;
100
+ before(async () => {
101
+ config = await testUtils.loadConfig('transform/offDelay.yml');
102
+ });
103
+
104
+ it('handles engine probe', function () {
105
+ const engine = new EngineV2(config);
106
+ const builder = new Builder(config);
107
+ builder.build(engine);
108
+
109
+ const source = testUtils.valueSource();
110
+ testUtils.attachEngineTransformValidator(engine, engine.variablePool.var1, source);
111
+
112
+ source.sendValues('active', [[false, 0], [true, 2], [false, 4], [true, 10], [false, 12]]);
113
+ source.probe(15);
114
+ source.probe(18);
115
+ source.sendValue('active', true, 18);
116
+
117
+ engine.validateFilter([
118
+ [false, 0], [true, 2], [true, 4], [false, 9], [true, 10], [true, 12],
119
+ [false, 17],
120
+ [true, 18],
121
+ ]);
122
+ });
123
+ });
@@ -0,0 +1,105 @@
1
+ 'use strict';
2
+
3
+ const expect = require('chai').expect;
4
+ const Source = require('../../lib/transform').source;
5
+ const OnDelay = require('../../lib/transform').onDelay;
6
+ const EngineV2 = require('../../lib/engine/engineV2');
7
+ const ExpressionService = require('../../lib/expressionService');
8
+ const testUtils = require('../util/testUtils');
9
+
10
+ describe('off-delay transform tests', function () {
11
+ it('on-delay regular', function () {
12
+ const filter = new OnDelay(3);
13
+ testUtils.attachTransformValidator(filter);
14
+
15
+ filter.testDigital('__^^__^^^^____^_^^^^^__^^^__^^^^|^^', 1);
16
+ filter.valdDigital('_________^_________^^_____|____^___', 1);
17
+ });
18
+
19
+ it('on-delay regular high lead', function () {
20
+ const filter = new OnDelay(3);
21
+ testUtils.attachTransformValidator(filter);
22
+
23
+ filter.testDigital('^^^^^', 1);
24
+ filter.valdDigital('___^^', 1);
25
+ });
26
+
27
+ it('on-delay irregular', function () {
28
+ // Without an engine to honor penching change times, off changes can be missed in gaps
29
+ const filter = new OnDelay(3);
30
+ testUtils.attachTransformValidator(filter);
31
+
32
+ filter.test([
33
+ [true, 2], [false, 4], [true, 6], [false, 10], [true, 14], [false, 15], [true, 16], [false, 21],
34
+ ]);
35
+ filter.validate([
36
+ [false, 2], [false, 4], [false, 6], [false, 10], [false, 14], [false, 15], [false, 16], [false, 21],
37
+ ]);
38
+ });
39
+
40
+ it('supports pending change', function () {
41
+ const filter = new OnDelay(3);
42
+ expect(filter.supportsPendingChanges()).to.eq(true);
43
+ expect(filter.nextPendingChange()).to.eq(null);
44
+
45
+ const context = { sourceType: 'test', trigger: 'test' };
46
+
47
+ filter.update(context, true, 3);
48
+ filter.update(context, false, 4);
49
+ filter.update(context, true, 5);
50
+ expect(filter.nextPendingChange()).to.eq(8);
51
+
52
+ filter.update(context, false, 5);
53
+ expect(filter.nextPendingChange()).to.eq(null);
54
+ filter.update(context, true, 6);
55
+ expect(filter.nextPendingChange()).to.eq(9);
56
+ filter.update(context, true, 7);
57
+ expect(filter.nextPendingChange()).to.eq(9);
58
+ filter.update(context, false, 11);
59
+ expect(filter.nextPendingChange()).to.eq(null);
60
+
61
+ filter.update(context, false, 12);
62
+ filter.update(context, true, 15);
63
+ expect(filter.nextPendingChange()).to.eq(18);
64
+ filter.update(context, true, 18);
65
+ expect(filter.nextPendingChange()).to.eq(null);
66
+
67
+ filter.update(context, false, 20);
68
+ filter.update(context, true, 22);
69
+ filter.setUnavailable(context, 23);
70
+ expect(filter.nextPendingChange()).to.eq(null);
71
+ });
72
+ });
73
+
74
+ describe('on-delay transform engine tests', function () {
75
+ it('on-delay irregular', function () {
76
+ const exprsvc = new ExpressionService();
77
+ const engine = new EngineV2({ expressionService: exprsvc });
78
+
79
+ exprsvc.addName({ name: 'pin-1', defaultValue: 0, channel: 'device' });
80
+ exprsvc.addExpression({ expression: 'pin-1', path: 'test1' });
81
+
82
+ const filter = new Source({
83
+ engine,
84
+ path: 'test1',
85
+ baseTransform: true,
86
+ args: {
87
+ expression: 'pin-1',
88
+ },
89
+ }).chain(new OnDelay(3));
90
+ engine.addVariable('res', filter);
91
+
92
+ testUtils.attachEngineTransformValidator(engine, filter);
93
+
94
+ engine.test([
95
+ [true, 2], [false, 4], [true, 6], [false, 10], [true, 14], [false, 15], [true, 16], [false, 21],
96
+ ]);
97
+ engine.validateFilter([
98
+ [false, 2], [false, 4], [false, 6], [true, 9], [false, 10], [false, 14],
99
+ [false, 15], [false, 16], [true, 19], [false, 21],
100
+ ]);
101
+ engine.validateEngine('res', [
102
+ [false, 2], [true, 9], [false, 10], [true, 19], [false, 21],
103
+ ]);
104
+ });
105
+ });
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ const PatternEscape = require('../../lib/transform').patternEscape;
4
+ const testUtils = require('../util/testUtils');
5
+
6
+ describe('pattern-escape transform tests', async function () {
7
+ const setupFilter = () => {
8
+ return new PatternEscape();
9
+ };
10
+
11
+ it('pattern escape', async function () {
12
+ const filter = setupFilter();
13
+
14
+ await testUtils.testValue(filter, 'a regular string', 'a regular string');
15
+ await testUtils.testValue(filter, 'a+b+c', 'a\\+b\\+c');
16
+ await testUtils.testValue(filter, 'bulba(saur), what? stop.', 'bulba\\(saur\\), what\\? stop\\.');
17
+ });
18
+ });
@@ -0,0 +1,177 @@
1
+ 'use strict';
2
+
3
+ const EngineV2 = require('../../lib/engine/engineV2');
4
+ const Builder = require('../../lib/engine/transformBuilderV2');
5
+ const testUtils = require('../util/testUtils');
6
+
7
+ describe('pattern-match config file tests', async function () {
8
+ let config;
9
+ before(async () => {
10
+ config = await testUtils.loadConfig('transform/pattern-match.yml');
11
+ });
12
+
13
+ const makeSourceEngine = (varName) => {
14
+ const engine = new EngineV2(config);
15
+ const builder = new Builder(config);
16
+ builder.build(engine);
17
+
18
+ const source = testUtils.valueSource();
19
+ testUtils.attachEngineTransformValidator(engine, engine.variablePool[varName], source);
20
+
21
+ return { source, engine };
22
+ };
23
+
24
+ it('reads minimal escaped js-style pattern', async function () {
25
+ const { source, engine } = makeSourceEngine('match1');
26
+
27
+ source.sendValues('program', [
28
+ ['this is a test01060', 0],
29
+ ['nope123', 2],
30
+ ['case-insensitive TeSt789', 4]
31
+ ]);
32
+
33
+ engine.validateFilter([
34
+ ['test01060', 0],
35
+ ['', 2],
36
+ ['TeSt789', 4],
37
+ ]);
38
+ });
39
+
40
+ it('reads fugly escaped string pattern', async function () {
41
+ const { source, engine } = makeSourceEngine('match2');
42
+
43
+ source.sendValues('program', [
44
+ ['this is a test01060', 0],
45
+ ['nope123', 2],
46
+ ]);
47
+
48
+ engine.validateFilter([
49
+ ['test01060', 0],
50
+ ['', 2],
51
+ ]);
52
+ });
53
+
54
+ it('reads extended config entry', async function () {
55
+ const { source, engine } = makeSourceEngine('match3');
56
+
57
+ source.sendValues('program', [
58
+ ['this is a test01060', 0],
59
+ ['nope123', 2],
60
+ ['case-insensitive TeSt789', 4]
61
+ ]);
62
+
63
+ engine.validateFilter([
64
+ ['01060', 0],
65
+ ['NOMATCH', 2],
66
+ ['789', 4],
67
+ ]);
68
+ });
69
+
70
+ it('reads shorthand with expression', async function () {
71
+ const { source, engine } = makeSourceEngine('match4');
72
+
73
+ source.sendValue('pat1', '\\d+');
74
+
75
+ source.sendValues('program', [
76
+ ['this is a test01060', 0],
77
+ ['nope123', 2],
78
+ ['case-insensitive TeSt789', 4]
79
+ ]);
80
+
81
+ engine.validateFilter([
82
+ ['test01060', 0],
83
+ ['', 2],
84
+ ['TeSt789', 4],
85
+ ]);
86
+ });
87
+
88
+ it('reads extended with expression', async function () {
89
+ const { source, engine } = makeSourceEngine('match5');
90
+
91
+ source.sendValue('pat1', '\\d+');
92
+
93
+ source.sendValues('program', [
94
+ ['this is a test01060', 0],
95
+ ['nope123', 2],
96
+ ['case-insensitive TeSt789', 4]
97
+ ]);
98
+
99
+ engine.validateFilter([
100
+ ['01060', 0],
101
+ ['no match nope123', 2],
102
+ ['789', 4],
103
+ ]);
104
+ });
105
+
106
+ it('reads pattern with index', async function () {
107
+ const { source, engine } = makeSourceEngine('match6');
108
+
109
+ source.sendValues('program', [
110
+ ['Sphinx of black quartz', 0],
111
+ ['Sphinx', 2],
112
+ ]);
113
+
114
+ engine.validateFilter([
115
+ ['of', 0],
116
+ ['', 2],
117
+ ]);
118
+ });
119
+
120
+ it('reads pattern with index and group', async function () {
121
+ const { source, engine } = makeSourceEngine('match7');
122
+
123
+ source.sendValues('program', [
124
+ ['End words.', 0],
125
+ ['Multiple words. Ending in dots.', 2],
126
+ ]);
127
+
128
+ engine.validateFilter([
129
+ ['', 0],
130
+ ['dots', 2],
131
+ ]);
132
+ });
133
+
134
+ it('reads pattern with implicit index via global flag', async function () {
135
+ const { source, engine } = makeSourceEngine('match8');
136
+
137
+ source.sendValues('program8', [
138
+ ['End words.', 0],
139
+ ['Multiple words. Ending in dots.', 2],
140
+ ]);
141
+
142
+ engine.validateFilter([
143
+ ['words.', 0],
144
+ ['words.', 2],
145
+ ]);
146
+ });
147
+
148
+ it('reads pattern with group and implicit index via global flag', async function () {
149
+ const { source, engine } = makeSourceEngine('match9');
150
+
151
+ source.sendValues('program9', [
152
+ ['End words.', 0],
153
+ ['Multiple words. Ending in dots.', 2],
154
+ ]);
155
+
156
+ engine.validateFilter([
157
+ ['words', 0],
158
+ ['words', 2],
159
+ ]);
160
+ });
161
+
162
+ it('reads extended config entry else 0', async function () {
163
+ const { source, engine } = makeSourceEngine('match10');
164
+
165
+ source.sendValues('program', [
166
+ ['this is a test01060', 0],
167
+ ['nope123', 2],
168
+ ['case-insensitive TeSt789', 4]
169
+ ]);
170
+
171
+ engine.validateFilter([
172
+ ['01060', 0],
173
+ [0, 2],
174
+ ['789', 4],
175
+ ]);
176
+ });
177
+ });
@@ -0,0 +1,95 @@
1
+ 'use strict';
2
+
3
+ const EngineV2 = require('../../lib/engine/engineV2');
4
+ const Builder = require('../../lib/engine/transformBuilderV2');
5
+ const testUtils = require('../util/testUtils');
6
+
7
+ describe('pattern-replace config file tests', async function () {
8
+ let config;
9
+ before(async () => {
10
+ config = await testUtils.loadConfig('transform/pattern-replace.yml');
11
+ });
12
+
13
+ const makeSourceEngine = (varName) => {
14
+ const engine = new EngineV2(config);
15
+ const builder = new Builder(config);
16
+ builder.build(engine);
17
+
18
+ const source = testUtils.valueSource();
19
+ testUtils.attachEngineTransformValidator(engine, engine.variablePool[varName], source);
20
+
21
+ return { source, engine };
22
+ };
23
+
24
+ it('reads minimal escaped js-style pattern', async function () {
25
+ const { source, engine } = makeSourceEngine('replace1');
26
+
27
+ source.sendValues('program', [
28
+ ['Replace test123 and test9006 but not testing', 0],
29
+ ['nope123', 2],
30
+ ['case TEST456 matters', 4]
31
+ ]);
32
+
33
+ engine.validateFilter([
34
+ ['Replace heck and heck but not testing', 0],
35
+ ['nope123', 2],
36
+ ['case TEST456 matters', 4],
37
+ ]);
38
+ });
39
+
40
+ it('reads extended config entry', async function () {
41
+ const { source, engine } = makeSourceEngine('replace2');
42
+
43
+ source.sendValues('program', [
44
+ ['Want to test123 something', 0],
45
+ ['nope123', 2],
46
+ ['case-insensitive TeSt789', 4]
47
+ ]);
48
+
49
+ engine.validateFilter([
50
+ ['Want to foo123 something', 0],
51
+ ['NOMATCH', 2],
52
+ ['case-insensitive foo789', 4],
53
+ ]);
54
+ });
55
+
56
+ it('reads config entry with multipart interpolation', async function () {
57
+ const { source, engine } = makeSourceEngine('replace3');
58
+
59
+ source.sendValue('xact', 10);
60
+ source.sendValue('yact', 20);
61
+ source.sendValue('pat1', '\\d');
62
+
63
+ source.sendValues('program', [
64
+ ['Replace test123 and test9006 but not testing', 0],
65
+ ['nope123', 2],
66
+ ['case TEST456 matters', 4]
67
+ ]);
68
+
69
+ engine.validateFilter([
70
+ ['Replace heck 10 and heck 10 but not testing', 0],
71
+ ['coord 10,20 (nope123)', 2],
72
+ ['coord 10,20 (case TEST456 matters)', 4],
73
+ ]);
74
+ });
75
+
76
+ it('reads config entry with singlepart expression', async function () {
77
+ const { source, engine } = makeSourceEngine('replace4');
78
+
79
+ source.sendValue('xact', 10);
80
+ source.sendValue('yact', 20);
81
+ source.sendValue('pat2', 'test\\d+');
82
+
83
+ source.sendValues('program', [
84
+ ['Replace test123 and test9006 but not testing', 0],
85
+ ['nope123', 2],
86
+ ['case TEST456 matters', 4]
87
+ ]);
88
+
89
+ engine.validateFilter([
90
+ ['Replace 200 and 200 but not testing', 0],
91
+ ['30', 2],
92
+ ['30', 4],
93
+ ]);
94
+ });
95
+ });
@@ -0,0 +1,105 @@
1
+ 'use strict';
2
+
3
+ const EngineV2 = require('../../lib/engine/engineV2');
4
+ const Builder = require('../../lib/engine/transformBuilderV2');
5
+ const testUtils = require('../util/testUtils');
6
+
7
+ describe('pattern-test config file tests', async function () {
8
+ let config;
9
+ before(async () => {
10
+ config = await testUtils.loadConfig('transform/pattern-test.yml');
11
+ });
12
+
13
+ const makeSourceEngine = (varName) => {
14
+ const engine = new EngineV2(config);
15
+ const builder = new Builder(config);
16
+ builder.build(engine);
17
+
18
+ const source = testUtils.valueSource();
19
+ testUtils.attachEngineTransformValidator(engine, engine.variablePool[varName], source);
20
+
21
+ return { source, engine };
22
+ };
23
+
24
+ it('reads minimal escaped js-style pattern', async function () {
25
+ const { source, engine } = makeSourceEngine('test1');
26
+
27
+ source.sendValues('program', [
28
+ ['this has a test01060', 0],
29
+ ['nope123', 2],
30
+ ['case-insensitive TeSt789', 4]
31
+ ]);
32
+
33
+ engine.validateFilter([
34
+ [true, 0],
35
+ [false, 2],
36
+ [false, 4],
37
+ ]);
38
+ });
39
+
40
+ it('reads fugly escaped string pattern', async function () {
41
+ const { source, engine } = makeSourceEngine('test2');
42
+
43
+ source.sendValues('program', [
44
+ ['this has a test01060', 0],
45
+ ['nope123', 2],
46
+ ]);
47
+
48
+ engine.validateFilter([
49
+ [true, 0],
50
+ [false, 2],
51
+ ]);
52
+ });
53
+
54
+ it('reads extended config entry', async function () {
55
+ const { source, engine } = makeSourceEngine('test3');
56
+
57
+ source.sendValues('program', [
58
+ ['this has a test01060', 0],
59
+ ['nope123', 2],
60
+ ['case-insensitive TeSt789', 4]
61
+ ]);
62
+
63
+ engine.validateFilter([
64
+ [true, 0],
65
+ [false, 2],
66
+ [true, 4],
67
+ ]);
68
+ });
69
+
70
+ it('reads minimal escaped js-style pattern with expression', async function () {
71
+ const { source, engine } = makeSourceEngine('test4');
72
+
73
+ source.sendValue('pat1', '\\d+', 0);
74
+
75
+ source.sendValues('program', [
76
+ ['this has a test01060', 0],
77
+ ['nope123', 2],
78
+ ['case-insensitive TeSt789', 4]
79
+ ]);
80
+
81
+ engine.validateFilter([
82
+ [true, 0],
83
+ [false, 2],
84
+ [false, 4],
85
+ ]);
86
+ });
87
+
88
+ it('reads extended config entry with expression', async function () {
89
+ const { source, engine } = makeSourceEngine('test5');
90
+
91
+ source.sendValue('pat1', '\\d+', 0);
92
+
93
+ source.sendValues('program', [
94
+ ['this has a test01060', 0],
95
+ ['nope123', 2],
96
+ ['case-insensitive TeSt789', 4]
97
+ ]);
98
+
99
+ engine.validateFilter([
100
+ [true, 0],
101
+ [false, 2],
102
+ [true, 4],
103
+ ]);
104
+ });
105
+ });