@hahnpro/flow-sdk 2025.2.0-beta.1 → 2025.2.0-beta.2

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 (79) hide show
  1. package/package.json +5 -4
  2. package/src/{index.ts → index.d.ts} +0 -3
  3. package/src/index.js +18 -0
  4. package/src/lib/ContextManager.d.ts +40 -0
  5. package/src/lib/ContextManager.js +105 -0
  6. package/src/lib/FlowApplication.d.ts +85 -0
  7. package/src/lib/FlowApplication.js +528 -0
  8. package/src/lib/FlowElement.d.ts +67 -0
  9. package/src/lib/FlowElement.js +178 -0
  10. package/src/lib/FlowEvent.d.ts +25 -0
  11. package/src/lib/FlowEvent.js +72 -0
  12. package/src/lib/FlowLogger.d.ts +44 -0
  13. package/src/lib/FlowLogger.js +110 -0
  14. package/src/lib/FlowModule.d.ts +7 -0
  15. package/src/lib/FlowModule.js +14 -0
  16. package/src/lib/RpcClient.d.ts +13 -0
  17. package/src/lib/RpcClient.js +88 -0
  18. package/src/lib/TestModule.d.ts +2 -0
  19. package/src/lib/TestModule.js +27 -0
  20. package/src/lib/amqp.d.ts +14 -0
  21. package/src/lib/amqp.js +12 -0
  22. package/src/lib/extra-validators.d.ts +1 -0
  23. package/src/lib/extra-validators.js +53 -0
  24. package/src/lib/flow.interface.d.ts +48 -0
  25. package/src/lib/flow.interface.js +9 -0
  26. package/src/lib/{index.ts → index.d.ts} +0 -3
  27. package/src/lib/index.js +18 -0
  28. package/src/lib/nats.d.ts +12 -0
  29. package/src/lib/nats.js +115 -0
  30. package/src/lib/unit-decorators.d.ts +39 -0
  31. package/src/lib/unit-decorators.js +156 -0
  32. package/src/lib/unit-utils.d.ts +8 -0
  33. package/src/lib/unit-utils.js +144 -0
  34. package/src/lib/units.d.ts +31 -0
  35. package/src/lib/units.js +572 -0
  36. package/src/lib/utils.d.ts +51 -0
  37. package/src/lib/utils.js +178 -0
  38. package/jest.config.ts +0 -10
  39. package/project.json +0 -41
  40. package/src/lib/ContextManager.ts +0 -111
  41. package/src/lib/FlowApplication.ts +0 -659
  42. package/src/lib/FlowElement.ts +0 -220
  43. package/src/lib/FlowEvent.ts +0 -73
  44. package/src/lib/FlowLogger.ts +0 -131
  45. package/src/lib/FlowModule.ts +0 -18
  46. package/src/lib/RpcClient.ts +0 -99
  47. package/src/lib/TestModule.ts +0 -14
  48. package/src/lib/__pycache__/rpc_server.cpython-310.pyc +0 -0
  49. package/src/lib/amqp.ts +0 -32
  50. package/src/lib/extra-validators.ts +0 -62
  51. package/src/lib/flow.interface.ts +0 -56
  52. package/src/lib/nats.ts +0 -140
  53. package/src/lib/unit-decorators.ts +0 -156
  54. package/src/lib/unit-utils.ts +0 -163
  55. package/src/lib/units.ts +0 -587
  56. package/src/lib/utils.ts +0 -176
  57. package/test/context-manager-purpose.spec.ts +0 -248
  58. package/test/context-manager.spec.ts +0 -55
  59. package/test/context.spec.ts +0 -180
  60. package/test/event.spec.ts +0 -155
  61. package/test/extra-validators.spec.ts +0 -84
  62. package/test/flow-logger.spec.ts +0 -104
  63. package/test/flow.spec.ts +0 -508
  64. package/test/input-stream.decorator.spec.ts +0 -379
  65. package/test/long-rpc.test.py +0 -14
  66. package/test/long-running-rpc.spec.ts +0 -60
  67. package/test/message.spec.ts +0 -57
  68. package/test/mocks/logger.mock.ts +0 -7
  69. package/test/mocks/nats-connection.mock.ts +0 -135
  70. package/test/mocks/nats-prepare.reals-nats.ts +0 -15
  71. package/test/rpc.spec.ts +0 -198
  72. package/test/rpc.test.py +0 -45
  73. package/test/rx.spec.ts +0 -92
  74. package/test/unit-decorator.spec.ts +0 -57
  75. package/test/utils.spec.ts +0 -210
  76. package/test/validation.spec.ts +0 -174
  77. package/tsconfig.json +0 -13
  78. package/tsconfig.lib.json +0 -22
  79. package/tsconfig.spec.json +0 -8
package/test/rpc.spec.ts DELETED
@@ -1,198 +0,0 @@
1
- import { join } from 'path';
2
- import { setTimeout } from 'timers/promises';
3
-
4
- import type { PythonShell } from 'python-shell';
5
-
6
- import { FlowApplication, FlowEvent, FlowFunction, FlowModule, FlowResource, InputStream } from '../src';
7
- import { loggerMock } from './mocks/logger.mock';
8
-
9
- /* eslint-disable no-console */
10
- describe('Flow RPC', () => {
11
- let flowApp: FlowApplication;
12
-
13
- beforeEach(async () => {
14
- const flow = {
15
- elements: [
16
- { id: 'testResource', module: 'test-module', functionFqn: 'test.resource.TestResource' },
17
- { id: 'testResource2', module: 'test-module', functionFqn: 'test.resource.TestResource' },
18
- ],
19
- connections: [
20
- { id: 'testConnection1', source: 'testTrigger', sourceStream: 'a', target: 'testResource', targetStream: 'a' },
21
- { id: 'testConnection2', source: 'testTrigger', sourceStream: 'b', target: 'testResource2', targetStream: 'b' },
22
- { id: 'testConnection1', source: 'testTrigger', sourceStream: 'b', target: 'testResource', targetStream: 'b' },
23
- { id: 'testConnection1', source: 'testTrigger', sourceStream: 'c', target: 'testResource', targetStream: 'c' },
24
- { id: 'testConnection1', source: 'testTrigger', sourceStream: 'd', target: 'testResource', targetStream: 'd' },
25
- { id: 'testConnection1', source: 'testTrigger', sourceStream: 'e', target: 'testResource', targetStream: 'e' },
26
- { id: 'testConnection1', source: 'testTrigger', sourceStream: 'f', target: 'testResource', targetStream: 'f' },
27
- ],
28
- context: {
29
- flowId: 'testFlow',
30
- deploymentId: 'testDeployment',
31
- },
32
- };
33
- flowApp = new FlowApplication([TestModule], flow, {
34
- amqpConfig: {},
35
- skipApi: true,
36
- explicitInit: true,
37
- logger: loggerMock,
38
- });
39
- await flowApp.init();
40
- await setTimeout(2000);
41
- });
42
-
43
- test('FLOW.RPC.1 publish message', (done) => {
44
- flowApp.subscribe('testResource.a', {
45
- next: async (event: FlowEvent) => {
46
- expect(event.getData()).toEqual({ res: 'foo' });
47
- await flowApp.destroy();
48
- done();
49
- },
50
- });
51
-
52
- flowApp.emit(new FlowEvent({ id: 'testTrigger' }, {}, 'a'));
53
- });
54
-
55
- test('FLOW.RPC.2 return sent value', (done) => {
56
- flowApp.subscribe('testResource.b', {
57
- next: async (event: FlowEvent) => {
58
- expect(event.getData()).toEqual(expect.objectContaining({ res: 'bar' }));
59
- await flowApp.destroy();
60
- done();
61
- },
62
- });
63
-
64
- flowApp.emit(new FlowEvent({ id: 'testTrigger' }, { value: 'bar' }, 'b'));
65
- });
66
-
67
- test('FLOW.RPC.3 error in remote procedure', (done) => {
68
- flowApp.subscribe('testResource.c', {
69
- next: async (event: FlowEvent) => {
70
- console.log(event.getData());
71
- expect(event.getData().err).toBeDefined();
72
- await flowApp.destroy();
73
- done();
74
- },
75
- });
76
-
77
- flowApp.emit(new FlowEvent({ id: 'testTrigger' }, {}, 'c'));
78
- });
79
-
80
- test('FLOW.RPC.4 should return argument', (done) => {
81
- flowApp.subscribe('testResource.d', {
82
- next: async (event: FlowEvent) => {
83
- expect(event.getData()).toEqual({ res: '10' });
84
- await flowApp.destroy();
85
- done();
86
- },
87
- });
88
-
89
- flowApp.emit(new FlowEvent({ id: 'testTrigger' }, {}, 'd'));
90
- });
91
-
92
- test('FLOW.RPC.5 rpc function does not exist', (done) => {
93
- flowApp.subscribe('testResource.e', {
94
- next: async (event: FlowEvent) => {
95
- expect(event.getData().err).toBeDefined();
96
- await flowApp.destroy();
97
- done();
98
- },
99
- });
100
-
101
- flowApp.emit(new FlowEvent({ id: 'testTrigger' }, {}, 'e'));
102
- });
103
-
104
- test('FLOW.RPC.6 rpc function returns numpy object', (done) => {
105
- flowApp.subscribe('testResource.f', {
106
- next: async (event: FlowEvent) => {
107
- expect(event.getData()).toEqual({ res: '100000000' });
108
- await flowApp.destroy();
109
- done();
110
- },
111
- });
112
-
113
- flowApp.emit(
114
- new FlowEvent(
115
- { id: 'testTrigger' },
116
- {
117
- powers: [
118
- { timestamp: 1234, powers: 567 },
119
- { timestamp: 89, powers: 1011 },
120
- ],
121
- },
122
- 'f',
123
- ),
124
- );
125
- });
126
- });
127
-
128
- @FlowFunction('test.resource.TestResource')
129
- class TestResource extends FlowResource {
130
- private shell: PythonShell;
131
-
132
- constructor(context) {
133
- super(context);
134
- this.shell = this.runPyRpcScript(join(__dirname, 'rpc.test.py'), 10);
135
- this.shell.on('error', (error) => console.log(error));
136
- this.shell.on('pythonError', (error) => console.log(error));
137
- this.shell.on('stderr', (error) => console.log(error));
138
- this.shell.on('message', (error) => console.log(error));
139
- }
140
-
141
- onDestroy = () => this.shell.kill();
142
-
143
- @InputStream('a')
144
- public async onA(event) {
145
- this.callRpcFunction('testA')
146
- .then((res: any) => {
147
- this.emitEvent({ res }, event, 'a');
148
- })
149
- .catch((err) => console.error(err));
150
- }
151
-
152
- @InputStream('b')
153
- public async onB(event) {
154
- this.callRpcFunction('testB', 'bar')
155
- .then((res: any) => this.emitEvent({ res }, event, 'b'))
156
- .catch((err) => this.logger.error(err));
157
- }
158
-
159
- @InputStream('c')
160
- public async onC(event) {
161
- this.callRpcFunction('testC')
162
- .then((res: any) => this.emitEvent({ res }, event, 'c'))
163
- .catch((err) => this.emitEvent({ err }, event, 'c'));
164
- }
165
-
166
- @InputStream('d')
167
- public async onD(event) {
168
- this.callRpcFunction('testD')
169
- .then((res: any) => this.emitEvent({ res }, event, 'd'))
170
- .catch((err) => this.emitEvent({ err }, event, 'd'));
171
- }
172
-
173
- @InputStream('e')
174
- public async onE(event) {
175
- this.callRpcFunction('testE')
176
- .then((res: any) => this.emitEvent({ res }, event, 'e'))
177
- .catch((err) => {
178
- this.logger.error(err);
179
- this.emitEvent({ err }, event, 'e');
180
- });
181
- }
182
-
183
- @InputStream('f')
184
- public async onF(event) {
185
- this.callRpcFunction('testF')
186
- .then((res: any) => this.emitOutput({ res }, 'f'))
187
- .catch((err) => {
188
- this.logger.error(err);
189
- this.emitOutput({ err }, 'f');
190
- });
191
- }
192
- }
193
-
194
- @FlowModule({
195
- name: 'test-module',
196
- declarations: [TestResource],
197
- })
198
- class TestModule {}
package/test/rpc.test.py DELETED
@@ -1,45 +0,0 @@
1
- import sys
2
- import numpy as np
3
- import json
4
-
5
- sys.path.append(sys.argv[1])
6
- from rpc_server import RemoteProcedure, start_consumer
7
-
8
-
9
- class NpEncoder(json.JSONEncoder):
10
- def default(self, obj):
11
- if isinstance(obj, np.integer):
12
- return int(obj)
13
- if isinstance(obj, np.floating):
14
- return float(obj)
15
- if isinstance(obj, np.ndarray):
16
- return obj.tolist()
17
- return json.JSONEncoder.default(self, obj)
18
-
19
-
20
- @RemoteProcedure
21
- def testA():
22
- return "foo"
23
-
24
-
25
- @RemoteProcedure
26
- def testB(arg):
27
- return arg
28
-
29
-
30
- @RemoteProcedure
31
- def testC():
32
- return 1 / 0
33
-
34
-
35
- @RemoteProcedure
36
- def testD():
37
- return sys.argv[3]
38
-
39
-
40
- @RemoteProcedure
41
- def testF():
42
- return np.power(100, 4, dtype=np.int64), NpEncoder
43
-
44
-
45
- start_consumer(sys.argv[2])
package/test/rx.spec.ts DELETED
@@ -1,92 +0,0 @@
1
- import { interval, Subject } from 'rxjs';
2
- import { take } from 'rxjs/operators';
3
-
4
- import { delay, FlowApplication, FlowEvent, FlowFunction, FlowModule, FlowResource, FlowTask, InputStream } from '../src';
5
- import { loggerMock } from './mocks/logger.mock';
6
-
7
- /* eslint-disable no-console */
8
- describe('rx', () => {
9
- test('FLOW.RX.1 rx', (done) => {
10
- const size = 3;
11
- const flow = {
12
- elements: [
13
- { id: 'testTrigger', module: 'test-module', functionFqn: 'test.resource.TestResource1' },
14
- { id: 'testResource1', module: 'test-module', functionFqn: 'test.resource.TestResource1' },
15
- { id: 'testResource2', module: 'test-module', functionFqn: 'test.resource.TestResource2' },
16
- { id: 'tap', module: 'test-module', functionFqn: 'operators.tap' },
17
- ],
18
- connections: [
19
- { id: 'testConnection1', source: 'testTrigger', target: 'testResource1' },
20
- { id: 'testConnection2', source: 'testResource1', target: 'testResource2' },
21
- { id: 'testConnection3', source: 'testResource1', target: 'tap' },
22
- ],
23
- };
24
- const flowApp = new FlowApplication([TestModule], flow, { skipApi: true, logger: loggerMock });
25
-
26
- flowApp.subscribe('tap.default', {
27
- next: (event: FlowEvent) => {
28
- expect(event.getData()).toEqual({ hello: 'world' });
29
- },
30
- });
31
-
32
- let count = 0;
33
- flowApp.subscribe('testResource2.default', {
34
- next: (event: FlowEvent) => {
35
- count++;
36
- expect(event.getData()).toEqual(expect.objectContaining({ foo: 'bar' }));
37
- if (count === size) {
38
- done();
39
- }
40
- },
41
- });
42
-
43
- const triggers = interval(1000);
44
- triggers.pipe(take(size)).subscribe((x) => {
45
- flowApp.emit(new FlowEvent({ id: 'testTrigger' }, {}));
46
- });
47
- }, 60000);
48
- });
49
-
50
- @FlowFunction('test.resource.TestResource1')
51
- class TestResource extends FlowResource {
52
- @InputStream('default')
53
- public async onDefault(event) {
54
- await delay(2000);
55
- return this.emitEvent({ hello: 'world' }, event);
56
- }
57
- }
58
-
59
- @FlowFunction('operators.tap')
60
- class Tap extends FlowTask {
61
- tap$: Subject<FlowEvent>;
62
-
63
- constructor(context) {
64
- super(context);
65
- this.tap$ = new Subject<FlowEvent>();
66
- this.tap$.subscribe({
67
- next: (event) => {
68
- this.emitEvent({}, event);
69
- },
70
- });
71
- }
72
-
73
- @InputStream()
74
- public async onDefault(event) {
75
- this.tap$.next(event);
76
- }
77
- }
78
-
79
- @FlowFunction('test.resource.TestResource2')
80
- class TestResource2 extends FlowResource {
81
- @InputStream('default', { concurrent: 1 })
82
- public async onDefault(event) {
83
- await delay(1000);
84
- return this.emitEvent({ foo: 'bar' }, event);
85
- }
86
- }
87
-
88
- @FlowModule({
89
- name: 'test-module',
90
- declarations: [TestResource, TestResource2, Tap],
91
- })
92
- class TestModule {}
@@ -1,57 +0,0 @@
1
- import { validationMetadatasToSchemas } from 'class-validator-jsonschema';
2
-
3
- import { IsVoltage } from '../src/lib/unit-decorators';
4
- import { computeUnitOptions, verifyUnit } from '../src/lib/unit-utils';
5
-
6
- class Test {
7
- @IsVoltage('YV')
8
- arg: number;
9
- }
10
-
11
- describe('unit decorators', () => {
12
- test('FLOW.UD.1 voltage', async () => {
13
- const schemas = validationMetadatasToSchemas({
14
- additionalConverters: {
15
- UnitArgsValidator: (meta) => {
16
- return {
17
- measure: meta.constraints[0],
18
- unit: meta.constraints[1],
19
- type: 'number',
20
- };
21
- },
22
- },
23
- });
24
-
25
- expect(schemas['Test'].properties.arg).toEqual({
26
- measure: 'voltage',
27
- unit: 'YV',
28
- type: 'number',
29
- });
30
- });
31
-
32
- test('FLOW.UD.2 verifyUnit', () => {
33
- expect(verifyUnit('in', 'length')).toEqual(1 / 39.3701);
34
- expect(verifyUnit('kNcm', 'torque')).toEqual(10);
35
- expect(verifyUnit('m/s', 'translationalVelocity')).toEqual(1);
36
- expect(verifyUnit('km/h', 'translationalVelocity')).toEqual(0.2777777777777778);
37
- expect(verifyUnit('kgm^2/s^2', 'torque')).toEqual(1);
38
- expect(verifyUnit('kgkm^2/s^2', 'torque')).toEqual(1e6);
39
- expect(verifyUnit('1/s', 'electricalFrequency')).toEqual(1);
40
- expect(verifyUnit('kHz', 'electricalFrequency')).toEqual(1000);
41
- expect(verifyUnit('W/m^2K', 'thermalTransmittance')).toEqual(1);
42
- expect(verifyUnit('Btu/hft^2F', 'thermalTransmittance')).toBeCloseTo(5.678);
43
- expect(verifyUnit('J/hm^2K', 'thermalTransmittance')).toEqual(1 / 3600);
44
- expect(verifyUnit('ft^2', 'area')).toBeCloseTo(0.0929);
45
-
46
- expect(verifyUnit('in', 'time')).toEqual(-1);
47
- expect(verifyUnit('kNmmm', 'torque')).toEqual(-1);
48
-
49
- expect(verifyUnit('', 'time')).toEqual(-1);
50
- expect(verifyUnit('min', '')).toEqual(-1);
51
- expect(verifyUnit('', '')).toEqual(-1);
52
- });
53
-
54
- test('FLOW.UD.3 computeUnits', () => {
55
- expect(computeUnitOptions('L-2')).toEqual(computeUnitOptions('L2'));
56
- });
57
- });
@@ -1,210 +0,0 @@
1
- import { fillTemplate } from '../src';
2
-
3
- describe('utils', () => {
4
- test('FLOW.UTIL.1 template string interpolation for flow properties', () => {
5
- let tmplString = '${test}';
6
- let tmplVars: any = { test: 'hello world' };
7
- let filled = fillTemplate(tmplString, tmplVars);
8
- expect(filled).toEqual('hello world');
9
-
10
- tmplString = '${foo.bar}';
11
- tmplVars = { foo: { bar: 'baz' } };
12
- filled = fillTemplate(tmplString, tmplVars);
13
- expect(filled).toEqual('baz');
14
-
15
- tmplString = '${path}';
16
- tmplVars = { path: 'Some.Random.path' };
17
- filled = fillTemplate(tmplString, tmplVars);
18
- expect(filled).toEqual('Some.Random.path');
19
-
20
- tmplString = 'foo';
21
- tmplVars = { foo: 'bar' };
22
- filled = fillTemplate(tmplString, tmplVars);
23
- expect(filled).toEqual('foo');
24
-
25
- tmplString = '${foo}';
26
- tmplVars = { foo: 0 };
27
- filled = fillTemplate(tmplString, tmplVars);
28
- expect(filled).toEqual('0');
29
-
30
- tmplString = '';
31
- tmplVars = { foo: 'bar' };
32
- filled = fillTemplate(tmplString, tmplVars);
33
- expect(filled).toEqual('');
34
-
35
- tmplString = null;
36
- tmplVars = null;
37
- filled = fillTemplate(tmplString, tmplVars);
38
- expect(filled).toEqual(null);
39
-
40
- tmplString = '${foo}';
41
- tmplVars = { foo: 'bar' };
42
- filled = fillTemplate(tmplString, tmplVars);
43
- expect(filled).toEqual('bar');
44
-
45
- tmplString = '4${foo}';
46
- tmplVars = { foo: 2 };
47
- filled = fillTemplate(tmplString, tmplVars);
48
- expect(filled).toEqual('42');
49
-
50
- tmplString = '${foo}';
51
- tmplVars = { foo: 42 };
52
- filled = fillTemplate(tmplString, tmplVars);
53
- expect(filled).toEqual('42');
54
-
55
- tmplString = '${foo.bar}';
56
- tmplVars = { foo: { bar: 'baz' } };
57
- filled = fillTemplate(tmplString, tmplVars);
58
- expect(filled).toEqual('baz');
59
-
60
- tmplString = '${foo}';
61
- tmplVars = { foo: 'bar', 'a-b': 'x' };
62
- filled = fillTemplate(tmplString, tmplVars);
63
- expect(filled).toEqual('bar');
64
-
65
- tmplString = '${x} ${y} c';
66
- tmplVars = { x: 'a', y: 'b' };
67
- filled = fillTemplate(tmplString, tmplVars);
68
- expect(filled).toEqual('a b c');
69
-
70
- tmplString = '${x}${y}${z}';
71
- tmplVars = { x: 'a', z: 'c' };
72
- filled = fillTemplate(tmplString, tmplVars);
73
- expect(filled).toEqual('ac');
74
-
75
- tmplString = '${foo}';
76
- tmplVars = {};
77
- filled = fillTemplate(tmplString, tmplVars);
78
- expect(filled).toEqual(undefined);
79
-
80
- tmplString = '${foo.bar.baz}';
81
- tmplVars = {};
82
- filled = fillTemplate(tmplString, tmplVars);
83
- expect(filled).toEqual(undefined);
84
-
85
- tmplString = '${foo}';
86
- tmplVars = undefined;
87
- filled = fillTemplate(tmplString, tmplVars);
88
- expect(filled).toEqual(undefined);
89
-
90
- tmplVars = null;
91
- filled = fillTemplate(tmplString, tmplVars);
92
- expect(filled).toEqual(undefined);
93
-
94
- tmplString = 'foo';
95
- filled = fillTemplate(tmplString, tmplVars);
96
- expect(filled).toEqual('foo');
97
- });
98
-
99
- test('FLOW.UTIL.2 deep interpolation', () => {
100
- let input: any = { foo: '${bar}' };
101
- let props: any = { bar: 'baz' };
102
- let res = fillTemplate(input, props);
103
- expect(res).toEqual({ foo: 'baz' });
104
-
105
- input = { foo: { x: ['a', 'b', '${bar}'] } };
106
- props = { bar: 'c' };
107
- res = fillTemplate(input, props);
108
- expect(res).toEqual({ foo: { x: ['a', 'b', 'c'] } });
109
-
110
- input = { a: { b: { c: { d: '${x}' } } } };
111
- props = { x: '42' };
112
- res = fillTemplate(input, props);
113
- expect(res).toEqual({ a: { b: { c: { d: '42' } } } });
114
-
115
- input = { a: { b: { c: { d: ['${x}', '${y}'] } } } };
116
- props = { x: '42', y: '23' };
117
- res = fillTemplate(input, props);
118
- expect(res).toEqual({ a: { b: { c: { d: ['42', '23'] } } } });
119
-
120
- input = { foo: [{ a: 'x', b: '${bar}' }, { c: '${baz}' }] };
121
- props = { bar: 'y', baz: 'z' };
122
- res = fillTemplate(input, props);
123
- expect(res).toEqual({ foo: [{ a: 'x', b: 'y' }, { c: 'z' }] });
124
-
125
- input = { foo: { x: ['a', 'b', '${bar}'] } };
126
- props = {};
127
- res = fillTemplate(input, props);
128
- expect(res).toEqual({ foo: { x: ['a', 'b', undefined] } });
129
-
130
- input = { foo: { x: ['a', 'b', '${bar}'] } };
131
- props = null;
132
- res = fillTemplate(input, props);
133
- expect(res).toEqual({ foo: { x: ['a', 'b', undefined] } });
134
- });
135
-
136
- test('FLOW.UTIL.3 fillTemplate', () => {
137
- let tmplString = 'foo';
138
- let tmplVars: any = { foo: 'bar' };
139
- let filled = fillTemplate(tmplString, tmplVars);
140
- expect(filled).toEqual('foo');
141
-
142
- tmplString = '';
143
- tmplVars = { foo: 'bar' };
144
- filled = fillTemplate(tmplString, tmplVars);
145
- expect(filled).toEqual('');
146
-
147
- tmplString = null;
148
- tmplVars = null;
149
- filled = fillTemplate(tmplString, tmplVars);
150
- expect(filled).toEqual(null);
151
-
152
- tmplString = '${foo}';
153
- tmplVars = { foo: 'bar' };
154
- filled = fillTemplate(tmplString, tmplVars);
155
- expect(filled).toEqual('bar');
156
-
157
- tmplString = '4${foo}';
158
- tmplVars = { foo: 2 };
159
- filled = fillTemplate(tmplString, tmplVars);
160
- expect(filled).toEqual('42');
161
-
162
- tmplString = '${foo}';
163
- tmplVars = { foo: 42 };
164
- filled = fillTemplate(tmplString, tmplVars);
165
- expect(filled).toEqual('42');
166
-
167
- tmplString = '${foo.bar}';
168
- tmplVars = { foo: { bar: 'baz' } };
169
- filled = fillTemplate(tmplString, tmplVars);
170
- expect(filled).toEqual('baz');
171
-
172
- tmplString = '${foo}';
173
- tmplVars = { foo: 'bar', 'a-b': 'x' };
174
- filled = fillTemplate(tmplString, tmplVars);
175
- expect(filled).toEqual('bar');
176
-
177
- tmplString = '${x} ${y} c';
178
- tmplVars = { x: 'a', y: 'b' };
179
- filled = fillTemplate(tmplString, tmplVars);
180
- expect(filled).toEqual('a b c');
181
-
182
- tmplString = '${x}${y}${z}';
183
- tmplVars = { x: 'a', z: 'c' };
184
- filled = fillTemplate(tmplString, tmplVars);
185
- expect(filled).toEqual('ac');
186
-
187
- tmplString = '${foo}';
188
- tmplVars = {};
189
- filled = fillTemplate(tmplString, tmplVars);
190
- expect(filled).toEqual(undefined);
191
-
192
- tmplString = '${foo.bar.baz}';
193
- tmplVars = {};
194
- filled = fillTemplate(tmplString, tmplVars);
195
- expect(filled).toEqual(undefined);
196
-
197
- tmplString = '${foo}';
198
- tmplVars = undefined;
199
- filled = fillTemplate(tmplString, tmplVars);
200
- expect(filled).toEqual(undefined);
201
-
202
- tmplVars = null;
203
- filled = fillTemplate(tmplString, tmplVars);
204
- expect(filled).toEqual(undefined);
205
-
206
- tmplString = 'foo';
207
- filled = fillTemplate(tmplString, tmplVars);
208
- expect(filled).toEqual('foo');
209
- });
210
- });