@finos/legend-application-studio 28.13.2 → 28.13.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 (95) hide show
  1. package/lib/__lib__/LegendStudioApplicationNavigationContext.d.ts +1 -0
  2. package/lib/__lib__/LegendStudioApplicationNavigationContext.d.ts.map +1 -1
  3. package/lib/__lib__/LegendStudioApplicationNavigationContext.js +1 -0
  4. package/lib/__lib__/LegendStudioApplicationNavigationContext.js.map +1 -1
  5. package/lib/application/LegendStudioApplicationConfig.d.ts +5 -9
  6. package/lib/application/LegendStudioApplicationConfig.d.ts.map +1 -1
  7. package/lib/application/LegendStudioApplicationConfig.js +6 -10
  8. package/lib/application/LegendStudioApplicationConfig.js.map +1 -1
  9. package/lib/components/editor/ActivityBar.d.ts.map +1 -1
  10. package/lib/components/editor/ActivityBar.js +3 -3
  11. package/lib/components/editor/ActivityBar.js.map +1 -1
  12. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.js +15 -15
  13. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.js.map +1 -1
  14. package/lib/components/editor/editor-group/function-activator/FunctionEditor.d.ts +1 -1
  15. package/lib/components/editor/editor-group/function-activator/FunctionEditor.d.ts.map +1 -1
  16. package/lib/components/editor/editor-group/function-activator/FunctionEditor.js +55 -104
  17. package/lib/components/editor/editor-group/function-activator/FunctionEditor.js.map +1 -1
  18. package/lib/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.d.ts.map +1 -1
  19. package/lib/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.js +3 -3
  20. package/lib/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.js.map +1 -1
  21. package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.d.ts +22 -0
  22. package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.d.ts.map +1 -0
  23. package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.js +267 -0
  24. package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.js.map +1 -0
  25. package/lib/components/editor/side-bar/Explorer.d.ts.map +1 -1
  26. package/lib/components/editor/side-bar/Explorer.js +1 -25
  27. package/lib/components/editor/side-bar/Explorer.js.map +1 -1
  28. package/lib/index.css +1 -1
  29. package/lib/package.json +1 -1
  30. package/lib/stores/editor/editor-state/element-editor-state/{FunctionActivatorPromoteState.d.ts → FunctionActivatorState.d.ts} +9 -9
  31. package/lib/stores/editor/editor-state/element-editor-state/FunctionActivatorState.d.ts.map +1 -0
  32. package/lib/stores/editor/editor-state/element-editor-state/{FunctionActivatorPromoteState.js → FunctionActivatorState.js} +24 -24
  33. package/lib/stores/editor/editor-state/element-editor-state/FunctionActivatorState.js.map +1 -0
  34. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.d.ts +6 -5
  35. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.d.ts.map +1 -1
  36. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.js +6 -5
  37. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.js.map +1 -1
  38. package/lib/stores/editor/editor-state/element-editor-state/{FunctionActivatorBuilderState.d.ts → ToDelete_FunctionActivatorBuilderState.d.ts} +1 -1
  39. package/lib/stores/editor/editor-state/element-editor-state/ToDelete_FunctionActivatorBuilderState.d.ts.map +1 -0
  40. package/lib/stores/editor/editor-state/element-editor-state/{FunctionActivatorBuilderState.js → ToDelete_FunctionActivatorBuilderState.js} +1 -1
  41. package/lib/stores/editor/editor-state/element-editor-state/ToDelete_FunctionActivatorBuilderState.js.map +1 -0
  42. package/lib/stores/editor/editor-state/element-editor-state/function-activator/INTERNAL__UnknownFunctionActivatorEditorState.js +1 -1
  43. package/lib/stores/editor/editor-state/element-editor-state/function-activator/INTERNAL__UnknownFunctionActivatorEditorState.js.map +1 -1
  44. package/lib/stores/editor/editor-state/element-editor-state/function-activator/SnowflakeAppFunctionActivatorEditorState.d.ts +1 -1
  45. package/lib/stores/editor/editor-state/element-editor-state/function-activator/SnowflakeAppFunctionActivatorEditorState.d.ts.map +1 -1
  46. package/lib/stores/editor/editor-state/element-editor-state/function-activator/SnowflakeAppFunctionActivatorEditorState.js +2 -2
  47. package/lib/stores/editor/editor-state/element-editor-state/function-activator/SnowflakeAppFunctionActivatorEditorState.js.map +1 -1
  48. package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.d.ts +87 -0
  49. package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.d.ts.map +1 -0
  50. package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.js +422 -0
  51. package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.js.map +1 -0
  52. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.d.ts.map +1 -1
  53. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.js +1 -1
  54. package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.js.map +1 -1
  55. package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.d.ts +3 -17
  56. package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.d.ts.map +1 -1
  57. package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.js +8 -69
  58. package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.js.map +1 -1
  59. package/lib/stores/editor/editor-state/element-editor-state/testable/TestableEditorState.d.ts +26 -3
  60. package/lib/stores/editor/editor-state/element-editor-state/testable/TestableEditorState.d.ts.map +1 -1
  61. package/lib/stores/editor/editor-state/element-editor-state/testable/TestableEditorState.js +72 -1
  62. package/lib/stores/editor/editor-state/element-editor-state/testable/TestableEditorState.js.map +1 -1
  63. package/lib/stores/graph-modifier/DomainGraphModifierHelper.d.ts +4 -1
  64. package/lib/stores/graph-modifier/DomainGraphModifierHelper.d.ts.map +1 -1
  65. package/lib/stores/graph-modifier/DomainGraphModifierHelper.js +10 -1
  66. package/lib/stores/graph-modifier/DomainGraphModifierHelper.js.map +1 -1
  67. package/lib/stores/graph-modifier/Testable_GraphModifierHelper.d.ts +3 -2
  68. package/lib/stores/graph-modifier/Testable_GraphModifierHelper.d.ts.map +1 -1
  69. package/lib/stores/graph-modifier/Testable_GraphModifierHelper.js +3 -0
  70. package/lib/stores/graph-modifier/Testable_GraphModifierHelper.js.map +1 -1
  71. package/package.json +4 -4
  72. package/src/__lib__/LegendStudioApplicationNavigationContext.ts +1 -0
  73. package/src/application/LegendStudioApplicationConfig.ts +7 -12
  74. package/src/components/editor/ActivityBar.tsx +4 -3
  75. package/src/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.tsx +36 -36
  76. package/src/components/editor/editor-group/function-activator/FunctionEditor.tsx +136 -345
  77. package/src/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.tsx +3 -10
  78. package/src/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.tsx +879 -0
  79. package/src/components/editor/side-bar/Explorer.tsx +0 -59
  80. package/src/stores/editor/editor-state/element-editor-state/{FunctionActivatorPromoteState.ts → FunctionActivatorState.ts} +23 -23
  81. package/src/stores/editor/editor-state/element-editor-state/FunctionEditorState.ts +7 -6
  82. package/src/stores/editor/editor-state/element-editor-state/function-activator/INTERNAL__UnknownFunctionActivatorEditorState.ts +1 -1
  83. package/src/stores/editor/editor-state/element-editor-state/function-activator/SnowflakeAppFunctionActivatorEditorState.ts +2 -2
  84. package/src/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.ts +646 -0
  85. package/src/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.ts +1 -4
  86. package/src/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.ts +16 -97
  87. package/src/stores/editor/editor-state/element-editor-state/testable/TestableEditorState.ts +105 -3
  88. package/src/stores/graph-modifier/DomainGraphModifierHelper.ts +34 -2
  89. package/src/stores/graph-modifier/Testable_GraphModifierHelper.ts +9 -1
  90. package/tsconfig.json +4 -2
  91. package/lib/stores/editor/editor-state/element-editor-state/FunctionActivatorBuilderState.d.ts.map +0 -1
  92. package/lib/stores/editor/editor-state/element-editor-state/FunctionActivatorBuilderState.js.map +0 -1
  93. package/lib/stores/editor/editor-state/element-editor-state/FunctionActivatorPromoteState.d.ts.map +0 -1
  94. package/lib/stores/editor/editor-state/element-editor-state/FunctionActivatorPromoteState.js.map +0 -1
  95. /package/src/stores/editor/editor-state/element-editor-state/{FunctionActivatorBuilderState.ts → ToDelete_FunctionActivatorBuilderState.ts} +0 -0
@@ -0,0 +1,646 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { action, flow, makeObservable, observable } from 'mobx';
18
+ import type { EditorStore } from '../../../../EditorStore.js';
19
+ import type { FunctionEditorState } from '../../FunctionEditorState.js';
20
+ import {
21
+ assertErrorThrown,
22
+ isNonNullable,
23
+ uuid,
24
+ type GeneratorFn,
25
+ LogEvent,
26
+ guaranteeNonNullable,
27
+ addUniqueEntry,
28
+ uniq,
29
+ assertTrue,
30
+ guaranteeType,
31
+ } from '@finos/legend-shared';
32
+ import {
33
+ type ConcreteFunctionDefinition,
34
+ type EmbeddedData,
35
+ type TestResult,
36
+ type AtomicTest,
37
+ type EngineRuntime,
38
+ type ObserverContext,
39
+ type ValueSpecification,
40
+ FunctionTest,
41
+ UniqueTestId,
42
+ FunctionStoreTestData,
43
+ FunctionTestSuite,
44
+ RunTestsTestableInput,
45
+ RawLambda,
46
+ PackageableRuntime,
47
+ SimpleFunctionExpression,
48
+ LambdaFunctionInstanceValue,
49
+ SUPPORTED_FUNCTIONS,
50
+ matchFunctionName,
51
+ InstanceValue,
52
+ PackageableElementReference,
53
+ Database,
54
+ RelationalCSVData,
55
+ PackageableElementExplicitReference,
56
+ } from '@finos/legend-graph';
57
+ import {
58
+ TestablePackageableElementEditorState,
59
+ TestableTestEditorState,
60
+ TestableTestSuiteEditorState,
61
+ } from '../../testable/TestableEditorState.js';
62
+ import { EmbeddedDataEditorState } from '../../data/DataEditorState.js';
63
+ import {
64
+ functionTestable_deleteDataStore,
65
+ functionTestable_setEmbeddedData,
66
+ function_addTestSuite,
67
+ } from '../../../../../graph-modifier/DomainGraphModifierHelper.js';
68
+ import {
69
+ DEFAULT_TEST_ASSERTION_ID,
70
+ createDefaultEqualToJSONTestAssertion,
71
+ isTestPassing,
72
+ } from '../../../../utils/TestableUtils.js';
73
+ import { LEGEND_STUDIO_APP_EVENT } from '../../../../../../__lib__/LegendStudioEvent.js';
74
+ import { testSuite_addTest } from '../../../../../graph-modifier/Testable_GraphModifierHelper.js';
75
+
76
+ const addToFunctionMap = (
77
+ val: SimpleFunctionExpression,
78
+ functions: Map<string, SimpleFunctionExpression[]>,
79
+ ): boolean => {
80
+ const values = functions.get(val.functionName) ?? [];
81
+ if (values.includes(val)) {
82
+ return false;
83
+ }
84
+ addUniqueEntry(values, val);
85
+ functions.set(val.functionName, values);
86
+ return true;
87
+ };
88
+
89
+ const collectSimpleFunctionExpressions = (
90
+ val: ValueSpecification,
91
+ functions: Map<string, SimpleFunctionExpression[]>,
92
+ ): void => {
93
+ if (val instanceof SimpleFunctionExpression) {
94
+ const continueProcessing = addToFunctionMap(val, functions);
95
+ if (continueProcessing) {
96
+ val.parametersValues.forEach((v) =>
97
+ collectSimpleFunctionExpressions(v, functions),
98
+ );
99
+ }
100
+ }
101
+ };
102
+
103
+ const resolveRuntimesFromQuery = (
104
+ func: ConcreteFunctionDefinition,
105
+ editorStore: EditorStore,
106
+ ): EngineRuntime[] | undefined => {
107
+ try {
108
+ const body = func.expressionSequence;
109
+ const rawLambda = new RawLambda([], body);
110
+ const functions = new Map<string, SimpleFunctionExpression[]>();
111
+ const valueSpec =
112
+ editorStore.graphManagerState.graphManager.buildValueSpecification(
113
+ editorStore.graphManagerState.graphManager.serializeRawValueSpecification(
114
+ rawLambda,
115
+ ),
116
+ editorStore.graphManagerState.graph,
117
+ );
118
+ if (valueSpec instanceof LambdaFunctionInstanceValue) {
119
+ const vals = guaranteeNonNullable(
120
+ valueSpec.values[0],
121
+ 'function expected to be of type lambda',
122
+ ).expressionSequence;
123
+ vals.forEach((v) => collectSimpleFunctionExpressions(v, functions));
124
+ const fromFunctions = Array.from(functions.keys())
125
+ .filter((v) => matchFunctionName(v, SUPPORTED_FUNCTIONS.FROM))
126
+ .map((e) => functions.get(e))
127
+ .flat()
128
+ .filter(isNonNullable);
129
+ const runtimeInstance: PackageableRuntime[] = [];
130
+ fromFunctions.forEach((v) => {
131
+ v.parametersValues.forEach((p) => {
132
+ if (p instanceof InstanceValue) {
133
+ p.values.forEach((pIn) => {
134
+ if (pIn instanceof PackageableElementReference) {
135
+ if (pIn.value instanceof PackageableRuntime) {
136
+ runtimeInstance.push(pIn.value);
137
+ }
138
+ }
139
+ });
140
+ }
141
+ });
142
+ });
143
+ return uniq(runtimeInstance.map((e) => e.runtimeValue).flat());
144
+ }
145
+ return [];
146
+ } catch (error) {
147
+ assertErrorThrown(error);
148
+ editorStore.applicationStore.logService.error(
149
+ LogEvent.create(LEGEND_STUDIO_APP_EVENT.SERVICE_TEST_SETUP_FAILURE),
150
+ error,
151
+ );
152
+ return undefined;
153
+ }
154
+ };
155
+
156
+ export class FunctionStoreTestDataState {
157
+ readonly editorStore: EditorStore;
158
+ readonly testDataState: FunctionTestDataState;
159
+ storeTestData: FunctionStoreTestData;
160
+ embeddedEditorState: EmbeddedDataEditorState;
161
+ dataElementModal = false;
162
+
163
+ constructor(
164
+ editorStore: EditorStore,
165
+ testDataState: FunctionTestDataState,
166
+ value: FunctionStoreTestData,
167
+ ) {
168
+ makeObservable(this, {
169
+ storeTestData: observable,
170
+ dataElementModal: observable,
171
+ embeddedEditorState: observable,
172
+
173
+ setDataElementModal: action,
174
+ changeEmbeddedData: action,
175
+ });
176
+ this.editorStore = editorStore;
177
+ this.testDataState = testDataState;
178
+ this.storeTestData = value;
179
+ this.embeddedEditorState = new EmbeddedDataEditorState(
180
+ this.testDataState.editorStore,
181
+ this.storeTestData.data,
182
+ {
183
+ hideSource: true,
184
+ },
185
+ );
186
+ }
187
+
188
+ setDataElementModal(val: boolean): void {
189
+ this.dataElementModal = val;
190
+ }
191
+
192
+ changeEmbeddedData(val: EmbeddedData): void {
193
+ functionTestable_setEmbeddedData(
194
+ this.storeTestData,
195
+ val,
196
+ this.editorStore.changeDetectionState.observerContext,
197
+ );
198
+ this.embeddedEditorState = new EmbeddedDataEditorState(
199
+ this.testDataState.editorStore,
200
+ this.storeTestData.data,
201
+ );
202
+ }
203
+ }
204
+
205
+ export class FunctionTestState extends TestableTestEditorState {
206
+ readonly parentState: FunctionTestSuiteState;
207
+ readonly functionTestableState: FunctionTestableState;
208
+ readonly uuid = uuid();
209
+ override test: FunctionTest;
210
+ // TODO: param
211
+
212
+ constructor(
213
+ editorStore: EditorStore,
214
+ parentSuiteState: FunctionTestSuiteState,
215
+ test: FunctionTest,
216
+ ) {
217
+ super(
218
+ parentSuiteState.functionTestableState.function,
219
+ test,
220
+ parentSuiteState.functionTestableState.functionEditorState.isReadOnly,
221
+ editorStore,
222
+ );
223
+ makeObservable(this, {
224
+ selectedAsertionState: observable,
225
+ selectedTab: observable,
226
+ assertionToRename: observable,
227
+ assertionEditorStates: observable,
228
+ testResultState: observable,
229
+ runningTestAction: observable,
230
+ addAssertion: action,
231
+ setAssertionToRename: action,
232
+ handleTestResult: action,
233
+ setSelectedTab: action,
234
+ runTest: flow,
235
+ });
236
+ this.parentState = parentSuiteState;
237
+ this.functionTestableState = parentSuiteState.functionTestableState;
238
+ this.test = test;
239
+ }
240
+ }
241
+
242
+ class FunctionTestDataState {
243
+ readonly editorStore: EditorStore;
244
+ readonly functionTestableState: FunctionTestableState;
245
+ selectedDataState: FunctionStoreTestDataState | undefined;
246
+ dataHolder: FunctionTestSuite;
247
+ showNewModal = false;
248
+
249
+ constructor(
250
+ editorStore: EditorStore,
251
+ functionTestableState: FunctionTestableState,
252
+ holder: FunctionTestSuite,
253
+ ) {
254
+ makeObservable(this, {
255
+ selectedDataState: observable,
256
+ dataHolder: observable,
257
+ showNewModal: observable,
258
+ initDefaultStore: action,
259
+ setShowModal: action,
260
+ deleteStoreTestData: action,
261
+ openStoreTestData: action,
262
+ });
263
+ this.editorStore = editorStore;
264
+ this.functionTestableState = functionTestableState;
265
+ this.dataHolder = holder;
266
+ this.initDefaultStore();
267
+ }
268
+
269
+ initDefaultStore(): void {
270
+ const val = this.dataHolder.testData?.[0];
271
+ if (val) {
272
+ this.openStoreTestData(val);
273
+ } else {
274
+ this.selectedDataState = undefined;
275
+ }
276
+ }
277
+
278
+ setShowModal(val: boolean): void {
279
+ this.showNewModal = val;
280
+ }
281
+
282
+ deleteStoreTestData(val: FunctionStoreTestData): void {
283
+ functionTestable_deleteDataStore(this.dataHolder, val);
284
+ this.initDefaultStore();
285
+ }
286
+
287
+ openStoreTestData(val: FunctionStoreTestData): void {
288
+ this.selectedDataState = new FunctionStoreTestDataState(
289
+ this.editorStore,
290
+ this,
291
+ val,
292
+ );
293
+ }
294
+ }
295
+
296
+ export const createFunctionTest = (
297
+ id: string,
298
+ observerContext: ObserverContext,
299
+ suite?: FunctionTestSuite | undefined,
300
+ ): FunctionTest => {
301
+ const funcionTest = new FunctionTest();
302
+ funcionTest.id = id;
303
+ funcionTest.assertions = [
304
+ createDefaultEqualToJSONTestAssertion(DEFAULT_TEST_ASSERTION_ID),
305
+ ];
306
+ if (suite) {
307
+ funcionTest.__parent = suite;
308
+ testSuite_addTest(suite, funcionTest, observerContext);
309
+ }
310
+ const assertion = createDefaultEqualToJSONTestAssertion(`expectedAssertion`);
311
+ funcionTest.assertions = [assertion];
312
+ assertion.parentTest = funcionTest;
313
+ return funcionTest;
314
+ };
315
+ export class FunctionTestSuiteState extends TestableTestSuiteEditorState {
316
+ readonly functionTestableState: FunctionTestableState;
317
+ override suite: FunctionTestSuite;
318
+ override testStates: FunctionTestState[] = [];
319
+ override selectTestState: FunctionTestState | undefined;
320
+ dataState: FunctionTestDataState;
321
+
322
+ showCreateModal = false;
323
+
324
+ constructor(
325
+ editorStore: EditorStore,
326
+ functionTestableState: FunctionTestableState,
327
+ suite: FunctionTestSuite,
328
+ ) {
329
+ super(
330
+ functionTestableState.function,
331
+ suite,
332
+ functionTestableState.functionEditorState.isReadOnly,
333
+ editorStore,
334
+ );
335
+ makeObservable(this, {
336
+ dataState: observable,
337
+ showCreateModal: observable,
338
+ selectTestState: observable,
339
+ changeTest: observable,
340
+ buildTestState: action,
341
+ deleteTest: action,
342
+ buildTestStates: action,
343
+ setShowModal: action,
344
+ addNewTest: action,
345
+ });
346
+ this.functionTestableState = functionTestableState;
347
+ this.suite = suite;
348
+ this.dataState = new FunctionTestDataState(
349
+ editorStore,
350
+ functionTestableState,
351
+ suite,
352
+ );
353
+ this.testStates = this.buildTestStates();
354
+ this.selectTestState = this.testStates[0];
355
+ }
356
+
357
+ setShowModal(val: boolean): void {
358
+ this.showCreateModal = val;
359
+ }
360
+
361
+ buildTestStates(): FunctionTestState[] {
362
+ return this.suite.tests
363
+ .map((t) => this.buildTestState(t))
364
+ .filter(isNonNullable);
365
+ }
366
+
367
+ buildTestState(val: AtomicTest): FunctionTestState | undefined {
368
+ if (val instanceof FunctionTest) {
369
+ return new FunctionTestState(this.editorStore, this, val);
370
+ }
371
+ return undefined;
372
+ }
373
+
374
+ addNewTest(id: string): void {
375
+ const test = createFunctionTest(
376
+ id,
377
+ this.editorStore.changeDetectionState.observerContext,
378
+ this.suite,
379
+ );
380
+
381
+ testSuite_addTest(
382
+ this.suite,
383
+ test,
384
+ this.functionTestableState.editorStore.changeDetectionState
385
+ .observerContext,
386
+ );
387
+ const testState = this.buildTestState(test);
388
+ if (testState) {
389
+ this.testStates.push(testState);
390
+ }
391
+ this.selectTestState = testState;
392
+ }
393
+ }
394
+
395
+ export class FunctionTestableState extends TestablePackageableElementEditorState {
396
+ readonly functionEditorState: FunctionEditorState;
397
+ declare selectedTestSuite: FunctionTestSuiteState | undefined;
398
+
399
+ runningSuite: FunctionTestSuite | undefined;
400
+ createSuiteModal = false;
401
+
402
+ constructor(functionEditorState: FunctionEditorState) {
403
+ super(functionEditorState, functionEditorState.functionElement);
404
+ makeObservable(this, {
405
+ isRunningTestableSuitesState: observable,
406
+ isRunningFailingSuitesState: observable,
407
+ selectedTestSuite: observable,
408
+ testableResults: observable,
409
+ runningSuite: observable,
410
+ createSuiteModal: observable,
411
+ init: action,
412
+ buildTestSuiteState: action,
413
+ deleteTestSuite: action,
414
+ changeSuite: action,
415
+ handleNewResults: action,
416
+ setRenameComponent: action,
417
+ clearTestResultsForSuite: action,
418
+ setCreateSuite: action,
419
+ runTestable: flow,
420
+ runSuite: flow,
421
+ runAllFailingSuites: flow,
422
+ });
423
+ this.functionEditorState = functionEditorState;
424
+ this.init();
425
+ }
426
+
427
+ get function(): ConcreteFunctionDefinition {
428
+ return this.functionEditorState.functionElement;
429
+ }
430
+
431
+ get passingSuites(): FunctionTestSuite[] {
432
+ const results = this.testableResults;
433
+ if (results?.length) {
434
+ return this.function.tests.filter((suite) =>
435
+ results
436
+ .filter((res) => res.parentSuite?.id === suite.id)
437
+ .every((e) => isTestPassing(e)),
438
+ );
439
+ }
440
+ return [];
441
+ }
442
+
443
+ get failingSuites(): FunctionTestSuite[] {
444
+ const results = this.testableResults;
445
+ if (results?.length) {
446
+ return this.function.tests.filter((suite) =>
447
+ results
448
+ .filter((res) => res.parentSuite?.id === suite.id)
449
+ .some((e) => !isTestPassing(e)),
450
+ );
451
+ }
452
+ return [];
453
+ }
454
+
455
+ get staticSuites(): FunctionTestSuite[] {
456
+ const results = this.testableResults;
457
+ if (results?.length) {
458
+ return this.function.tests.filter((suite) =>
459
+ results.every((res) => res.parentSuite?.id !== suite.id),
460
+ );
461
+ }
462
+ return this.function.tests;
463
+ }
464
+
465
+ init(): void {
466
+ if (!this.selectedTestSuite) {
467
+ const suite = this.function.tests[0];
468
+ this.selectedTestSuite = suite
469
+ ? this.buildTestSuiteState(suite)
470
+ : undefined;
471
+ }
472
+ }
473
+
474
+ setCreateSuite(val: boolean): void {
475
+ this.createSuiteModal = val;
476
+ }
477
+
478
+ createSuite(suiteName: string, testName: string): void {
479
+ const functionSuite = new FunctionTestSuite();
480
+ functionSuite.id = suiteName;
481
+ const engineRuntimes = resolveRuntimesFromQuery(
482
+ this.function,
483
+ this.editorStore,
484
+ );
485
+ if (engineRuntimes?.length) {
486
+ try {
487
+ assertTrue(
488
+ engineRuntimes.length === 1,
489
+ `Function Test Suite Only supports One Runtime at this time. Found ${engineRuntimes.length}`,
490
+ );
491
+ const engineRuntime = guaranteeNonNullable(engineRuntimes[0]);
492
+ assertTrue(
493
+ !(
494
+ engineRuntime.connectionStores.length &&
495
+ engineRuntime.connections.length
496
+ ),
497
+ `Runtime found has two connection types defined. Please use connection stores only`,
498
+ );
499
+ const stores = [
500
+ ...engineRuntime.connections
501
+ .map((e) =>
502
+ e.storeConnections.map((s) => s.connection.store.value).flat(),
503
+ )
504
+ .flat(),
505
+ ...engineRuntime.connectionStores
506
+ .map((e) => e.storePointers.map((sPt) => sPt.value))
507
+ .flat(),
508
+ ];
509
+ assertTrue(Boolean(stores.length), 'No runtime store found');
510
+ assertTrue(
511
+ stores.length === 1,
512
+ 'Only one store supported in runtime for function tests',
513
+ );
514
+ const store = guaranteeNonNullable(stores[0]);
515
+ guaranteeType(
516
+ store,
517
+ Database,
518
+ 'Only Database stores supported now for function test',
519
+ );
520
+ const relational = new RelationalCSVData();
521
+ const data = new FunctionStoreTestData();
522
+ data.store = PackageableElementExplicitReference.create(store);
523
+ data.data = relational;
524
+ functionSuite.testData = [data];
525
+ } catch (error) {
526
+ assertErrorThrown(error);
527
+ this.editorStore.applicationStore.notificationService.notifyError(
528
+ `Unable to create function test suite: ${error.message}`,
529
+ );
530
+ return;
531
+ }
532
+ }
533
+ createFunctionTest(
534
+ testName,
535
+ this.editorStore.changeDetectionState.observerContext,
536
+ functionSuite,
537
+ );
538
+ // set test suite
539
+ function_addTestSuite(
540
+ this.function,
541
+ functionSuite,
542
+ this.editorStore.changeDetectionState.observerContext,
543
+ );
544
+ this.changeSuite(functionSuite);
545
+ this.setCreateSuite(false);
546
+ }
547
+
548
+ *runSuite(suite: FunctionTestSuite): GeneratorFn<void> {
549
+ try {
550
+ this.runningSuite = suite;
551
+ this.clearTestResultsForSuite(suite);
552
+ this.selectedTestSuite?.testStates.forEach((t) => t.resetResult());
553
+ this.selectedTestSuite?.testStates.forEach((t) =>
554
+ t.runningTestAction.inProgress(),
555
+ );
556
+
557
+ const input = new RunTestsTestableInput(this.function);
558
+ suite.tests.forEach((t) =>
559
+ input.unitTestIds.push(new UniqueTestId(suite, t)),
560
+ );
561
+ const testResults =
562
+ (yield this.editorStore.graphManagerState.graphManager.runTests(
563
+ [input],
564
+ this.editorStore.graphManagerState.graph,
565
+ )) as TestResult[];
566
+
567
+ this.handleNewResults(testResults);
568
+ } catch (error) {
569
+ assertErrorThrown(error);
570
+ this.editorStore.applicationStore.notificationService.notifyError(error);
571
+ this.isRunningTestableSuitesState.fail();
572
+ } finally {
573
+ this.selectedTestSuite?.testStates.forEach((t) =>
574
+ t.runningTestAction.complete(),
575
+ );
576
+ this.runningSuite = undefined;
577
+ }
578
+ }
579
+
580
+ *runAllFailingSuites(): GeneratorFn<void> {
581
+ try {
582
+ this.isRunningFailingSuitesState.inProgress();
583
+ const input = new RunTestsTestableInput(this.testable);
584
+ this.failingSuites.forEach((s) => {
585
+ s.tests.forEach((t) => input.unitTestIds.push(new UniqueTestId(s, t)));
586
+ });
587
+ const testResults =
588
+ (yield this.editorStore.graphManagerState.graphManager.runTests(
589
+ [input],
590
+ this.editorStore.graphManagerState.graph,
591
+ )) as TestResult[];
592
+ this.handleNewResults(testResults);
593
+ this.isRunningFailingSuitesState.complete();
594
+ } catch (error) {
595
+ assertErrorThrown(error);
596
+ this.editorStore.applicationStore.notificationService.notifyError(error);
597
+ this.isRunningFailingSuitesState.fail();
598
+ } finally {
599
+ this.selectedTestSuite?.testStates.forEach((t) =>
600
+ t.runningTestAction.complete(),
601
+ );
602
+ }
603
+ }
604
+
605
+ handleNewResults(results: TestResult[]): void {
606
+ if (this.testableResults?.length) {
607
+ const newSuitesResults = results
608
+ .map((e) => e.parentSuite?.id)
609
+ .filter(isNonNullable);
610
+ const reducedFilters = this.testableResults.filter(
611
+ (res) => !newSuitesResults.includes(res.parentSuite?.id ?? ''),
612
+ );
613
+ this.setTestableResults([...reducedFilters, ...results]);
614
+ } else {
615
+ this.setTestableResults(results);
616
+ }
617
+ this.testableResults?.forEach((result) => {
618
+ const state = this.selectedTestSuite?.testStates.find(
619
+ (t) =>
620
+ t.test.id === result.atomicTest.id &&
621
+ t.parentState.suite.id === result.parentSuite?.id,
622
+ );
623
+ state?.handleTestResult(result);
624
+ });
625
+ }
626
+
627
+ clearTestResultsForSuite(suite: FunctionTestSuite): void {
628
+ this.testableResults = this.testableResults?.filter(
629
+ (t) => !(this.resolveSuiteResults(suite) ?? []).includes(t),
630
+ );
631
+ }
632
+
633
+ resolveSuiteResults(suite: FunctionTestSuite): TestResult[] | undefined {
634
+ return this.testableResults?.filter((t) => t.parentSuite?.id === suite.id);
635
+ }
636
+
637
+ buildTestSuiteState(val: FunctionTestSuite): FunctionTestSuiteState {
638
+ return new FunctionTestSuiteState(this.editorStore, this, val);
639
+ }
640
+
641
+ changeSuite(suite: FunctionTestSuite): void {
642
+ if (this.selectedTestSuite?.suite !== suite) {
643
+ this.selectedTestSuite = this.buildTestSuiteState(suite);
644
+ }
645
+ }
646
+ }
@@ -673,10 +673,7 @@ export class MappingEditorState extends ElementEditorState {
673
673
  this.mapping,
674
674
  editorStore,
675
675
  );
676
- this.mappingTestableState = new MappingTestableState(
677
- this.editorStore,
678
- this,
679
- );
676
+ this.mappingTestableState = new MappingTestableState(this);
680
677
  }
681
678
 
682
679
  get mapping(): Mapping {