@finos/legend-application-studio 28.13.1 → 28.13.3
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.
- package/lib/__lib__/LegendStudioApplicationNavigationContext.d.ts +1 -0
- package/lib/__lib__/LegendStudioApplicationNavigationContext.d.ts.map +1 -1
- package/lib/__lib__/LegendStudioApplicationNavigationContext.js +1 -0
- package/lib/__lib__/LegendStudioApplicationNavigationContext.js.map +1 -1
- package/lib/application/LegendStudioApplicationConfig.d.ts +5 -9
- package/lib/application/LegendStudioApplicationConfig.d.ts.map +1 -1
- package/lib/application/LegendStudioApplicationConfig.js +6 -10
- package/lib/application/LegendStudioApplicationConfig.js.map +1 -1
- package/lib/components/editor/ActivityBar.d.ts.map +1 -1
- package/lib/components/editor/ActivityBar.js +2 -2
- package/lib/components/editor/ActivityBar.js.map +1 -1
- package/lib/components/editor/editor-group/function-activator/FunctionEditor.d.ts +1 -1
- package/lib/components/editor/editor-group/function-activator/FunctionEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/function-activator/FunctionEditor.js +46 -95
- package/lib/components/editor/editor-group/function-activator/FunctionEditor.js.map +1 -1
- package/lib/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.js +3 -3
- package/lib/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.js.map +1 -1
- package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.d.ts +22 -0
- package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.d.ts.map +1 -0
- package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.js +231 -0
- package/lib/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.js.map +1 -0
- package/lib/components/editor/side-bar/Explorer.d.ts.map +1 -1
- package/lib/components/editor/side-bar/Explorer.js +1 -25
- package/lib/components/editor/side-bar/Explorer.js.map +1 -1
- package/lib/index.css +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/{FunctionActivatorPromoteState.d.ts → FunctionActivatorState.d.ts} +9 -9
- package/lib/stores/editor/editor-state/element-editor-state/FunctionActivatorState.d.ts.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/{FunctionActivatorPromoteState.js → FunctionActivatorState.js} +24 -25
- package/lib/stores/editor/editor-state/element-editor-state/FunctionActivatorState.js.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.d.ts +6 -5
- package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.js +6 -5
- package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/{FunctionActivatorBuilderState.d.ts → ToDelete_FunctionActivatorBuilderState.d.ts} +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/ToDelete_FunctionActivatorBuilderState.d.ts.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/{FunctionActivatorBuilderState.js → ToDelete_FunctionActivatorBuilderState.js} +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/ToDelete_FunctionActivatorBuilderState.js.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/INTERNAL__UnknownFunctionActivatorEditorState.js +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/INTERNAL__UnknownFunctionActivatorEditorState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/SnowflakeAppFunctionActivatorEditorState.d.ts +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/SnowflakeAppFunctionActivatorEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/SnowflakeAppFunctionActivatorEditorState.js +3 -2
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/SnowflakeAppFunctionActivatorEditorState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.d.ts +81 -0
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.d.ts.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.js +286 -0
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.js.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.js +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.d.ts +3 -17
- package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.js +8 -69
- package/lib/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/testable/TestableEditorState.d.ts +26 -3
- package/lib/stores/editor/editor-state/element-editor-state/testable/TestableEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/testable/TestableEditorState.js +72 -1
- package/lib/stores/editor/editor-state/element-editor-state/testable/TestableEditorState.js.map +1 -1
- package/lib/stores/graph-modifier/DomainGraphModifierHelper.d.ts +3 -1
- package/lib/stores/graph-modifier/DomainGraphModifierHelper.d.ts.map +1 -1
- package/lib/stores/graph-modifier/DomainGraphModifierHelper.js +7 -1
- package/lib/stores/graph-modifier/DomainGraphModifierHelper.js.map +1 -1
- package/lib/stores/graph-modifier/Testable_GraphModifierHelper.d.ts +3 -2
- package/lib/stores/graph-modifier/Testable_GraphModifierHelper.d.ts.map +1 -1
- package/lib/stores/graph-modifier/Testable_GraphModifierHelper.js +3 -0
- package/lib/stores/graph-modifier/Testable_GraphModifierHelper.js.map +1 -1
- package/package.json +4 -4
- package/src/__lib__/LegendStudioApplicationNavigationContext.ts +1 -0
- package/src/application/LegendStudioApplicationConfig.ts +7 -12
- package/src/components/editor/ActivityBar.tsx +3 -2
- package/src/components/editor/editor-group/function-activator/FunctionEditor.tsx +59 -276
- package/src/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.tsx +3 -10
- package/src/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.tsx +748 -0
- package/src/components/editor/side-bar/Explorer.tsx +0 -59
- package/src/stores/editor/editor-state/element-editor-state/{FunctionActivatorPromoteState.ts → FunctionActivatorState.ts} +23 -26
- package/src/stores/editor/editor-state/element-editor-state/FunctionEditorState.ts +7 -6
- package/src/stores/editor/editor-state/element-editor-state/function-activator/INTERNAL__UnknownFunctionActivatorEditorState.ts +1 -1
- package/src/stores/editor/editor-state/element-editor-state/function-activator/SnowflakeAppFunctionActivatorEditorState.ts +5 -2
- package/src/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.ts +414 -0
- package/src/stores/editor/editor-state/element-editor-state/mapping/MappingEditorState.ts +1 -4
- package/src/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.ts +16 -96
- package/src/stores/editor/editor-state/element-editor-state/testable/TestableEditorState.ts +105 -3
- package/src/stores/graph-modifier/DomainGraphModifierHelper.ts +23 -2
- package/src/stores/graph-modifier/Testable_GraphModifierHelper.ts +9 -1
- package/tsconfig.json +4 -2
- package/lib/stores/editor/editor-state/element-editor-state/FunctionActivatorBuilderState.d.ts.map +0 -1
- package/lib/stores/editor/editor-state/element-editor-state/FunctionActivatorBuilderState.js.map +0 -1
- package/lib/stores/editor/editor-state/element-editor-state/FunctionActivatorPromoteState.d.ts.map +0 -1
- package/lib/stores/editor/editor-state/element-editor-state/FunctionActivatorPromoteState.js.map +0 -1
- /package/src/stores/editor/editor-state/element-editor-state/{FunctionActivatorBuilderState.ts → ToDelete_FunctionActivatorBuilderState.ts} +0 -0
package/src/components/editor/editor-group/function-activator/testable/FunctionTestableEditor.tsx
ADDED
@@ -0,0 +1,748 @@
|
|
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 { observer } from 'mobx-react-lite';
|
18
|
+
import {
|
19
|
+
BlankPanelPlaceholder,
|
20
|
+
ContextMenu,
|
21
|
+
MenuContent,
|
22
|
+
MenuContentItem,
|
23
|
+
PanelContent,
|
24
|
+
PlayIcon,
|
25
|
+
PlusIcon,
|
26
|
+
ResizablePanel,
|
27
|
+
ResizablePanelGroup,
|
28
|
+
ResizablePanelSplitter,
|
29
|
+
ResizablePanelSplitterLine,
|
30
|
+
RunAllIcon,
|
31
|
+
RunErrorsIcon,
|
32
|
+
clsx,
|
33
|
+
} from '@finos/legend-art';
|
34
|
+
import { forwardRef, useEffect, useState } from 'react';
|
35
|
+
import {
|
36
|
+
type FunctionTestSuite,
|
37
|
+
type DataElement,
|
38
|
+
type EmbeddedData,
|
39
|
+
DataElementReference,
|
40
|
+
PackageableElementExplicitReference,
|
41
|
+
RelationalCSVData,
|
42
|
+
ModelStoreData,
|
43
|
+
ExternalFormatData,
|
44
|
+
ModelEmbeddedData,
|
45
|
+
} from '@finos/legend-graph';
|
46
|
+
import type {
|
47
|
+
FunctionStoreTestDataState,
|
48
|
+
FunctionTestState,
|
49
|
+
FunctionTestSuiteState,
|
50
|
+
FunctionTestableState,
|
51
|
+
} from '../../../../../stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.js';
|
52
|
+
import {
|
53
|
+
TESTABLE_RESULT,
|
54
|
+
getTestableResultFromTestResult,
|
55
|
+
getTestableResultFromTestResults,
|
56
|
+
} from '../../../../../stores/editor/sidebar-state/testable/GlobalTestRunnerState.js';
|
57
|
+
import { flowResult } from 'mobx';
|
58
|
+
import { getTestableResultIcon } from '../../../side-bar/testable/GlobalTestRunner.js';
|
59
|
+
import { atomicTest_setDoc } from '../../../../../stores/graph-modifier/Testable_GraphModifierHelper.js';
|
60
|
+
import {
|
61
|
+
RenameModal,
|
62
|
+
SharedDataElementModal,
|
63
|
+
TestAssertionEditor,
|
64
|
+
} from '../../testable/TestableSharedComponents.js';
|
65
|
+
import { returnUndefOnError } from '@finos/legend-shared';
|
66
|
+
import {
|
67
|
+
EmbeddedDataCreatorFromEmbeddedData,
|
68
|
+
validateTestableId,
|
69
|
+
} from '../../../../../stores/editor/utils/TestableUtils.js';
|
70
|
+
import { EmbeddedDataEditor } from '../../data-editor/EmbeddedDataEditor.js';
|
71
|
+
import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../../../../__lib__/LegendStudioApplicationNavigationContext.js';
|
72
|
+
import { useApplicationNavigationContext } from '@finos/legend-application';
|
73
|
+
|
74
|
+
const FunctionTestableContextMenu = observer(
|
75
|
+
forwardRef<
|
76
|
+
HTMLDivElement,
|
77
|
+
{
|
78
|
+
addName?: string;
|
79
|
+
_delete?: () => void;
|
80
|
+
rename?: () => void;
|
81
|
+
add?: () => void;
|
82
|
+
}
|
83
|
+
>(function TestContainerContextMenu(props, ref) {
|
84
|
+
const { addName, add, rename, _delete } = props;
|
85
|
+
const addTest = (): void => {
|
86
|
+
add?.();
|
87
|
+
};
|
88
|
+
const remove = (): void => _delete?.();
|
89
|
+
const handleRename = (): void => rename?.();
|
90
|
+
return (
|
91
|
+
<MenuContent ref={ref}>
|
92
|
+
{rename && (
|
93
|
+
<MenuContentItem onClick={handleRename}>Rename</MenuContentItem>
|
94
|
+
)}
|
95
|
+
{_delete && <MenuContentItem onClick={remove}>Delete</MenuContentItem>}
|
96
|
+
{addName && rename && (
|
97
|
+
<MenuContentItem
|
98
|
+
onClick={addTest}
|
99
|
+
>{`Add ${addName}`}</MenuContentItem>
|
100
|
+
)}
|
101
|
+
</MenuContent>
|
102
|
+
);
|
103
|
+
}),
|
104
|
+
);
|
105
|
+
|
106
|
+
const FunctionTestSuiteItem = observer(
|
107
|
+
(props: {
|
108
|
+
suite: FunctionTestSuite;
|
109
|
+
functionTestableState: FunctionTestableState;
|
110
|
+
}) => {
|
111
|
+
const { suite, functionTestableState } = props;
|
112
|
+
const [isSelectedFromContextMenu, setIsSelectedFromContextMenu] =
|
113
|
+
useState(false);
|
114
|
+
const isReadOnly = functionTestableState.functionEditorState.isReadOnly;
|
115
|
+
const openSuite = (): void => functionTestableState.changeSuite(suite);
|
116
|
+
const results = functionTestableState.testableResults?.filter(
|
117
|
+
(t) => t.parentSuite?.id === suite.id,
|
118
|
+
);
|
119
|
+
const isRunning =
|
120
|
+
functionTestableState.isRunningTestableSuitesState.isInProgress ||
|
121
|
+
(functionTestableState.isRunningFailingSuitesState.isInProgress &&
|
122
|
+
functionTestableState.failingSuites.includes(suite)) ||
|
123
|
+
functionTestableState.runningSuite === suite;
|
124
|
+
const isActive = functionTestableState.selectedTestSuite?.suite === suite;
|
125
|
+
const _testableResult = getTestableResultFromTestResults(results);
|
126
|
+
const testableResult = isRunning
|
127
|
+
? TESTABLE_RESULT.IN_PROGRESS
|
128
|
+
: _testableResult;
|
129
|
+
const resultIcon = getTestableResultIcon(testableResult);
|
130
|
+
const onContextMenuOpen = (): void => setIsSelectedFromContextMenu(true);
|
131
|
+
const onContextMenuClose = (): void => setIsSelectedFromContextMenu(false);
|
132
|
+
const add = (): void => {
|
133
|
+
// TODO
|
134
|
+
};
|
135
|
+
const _delete = (): void => {
|
136
|
+
functionTestableState.deleteTestSuite(suite);
|
137
|
+
};
|
138
|
+
const rename = (): void => {
|
139
|
+
functionTestableState.setRenameComponent(suite);
|
140
|
+
};
|
141
|
+
const runSuite = (): void => {
|
142
|
+
flowResult(functionTestableState.runSuite(suite)).catch(
|
143
|
+
functionTestableState.editorStore.applicationStore.alertUnhandledError,
|
144
|
+
);
|
145
|
+
};
|
146
|
+
return (
|
147
|
+
<ContextMenu
|
148
|
+
className={clsx(
|
149
|
+
'testable-test-explorer__item',
|
150
|
+
{
|
151
|
+
'testable-test-explorer__item--selected-from-context-menu':
|
152
|
+
!isActive && isSelectedFromContextMenu,
|
153
|
+
},
|
154
|
+
{ 'testable-test-explorer__item--active': isActive },
|
155
|
+
)}
|
156
|
+
disabled={isReadOnly}
|
157
|
+
content={
|
158
|
+
<FunctionTestableContextMenu
|
159
|
+
addName="Suite"
|
160
|
+
add={add}
|
161
|
+
_delete={_delete}
|
162
|
+
rename={rename}
|
163
|
+
/>
|
164
|
+
}
|
165
|
+
menuProps={{ elevation: 7 }}
|
166
|
+
onOpen={onContextMenuOpen}
|
167
|
+
onClose={onContextMenuClose}
|
168
|
+
>
|
169
|
+
<button
|
170
|
+
className={clsx('testable-test-explorer__item__label')}
|
171
|
+
onClick={openSuite}
|
172
|
+
tabIndex={-1}
|
173
|
+
>
|
174
|
+
<div className="testable-test-explorer__item__label__icon">
|
175
|
+
{resultIcon}
|
176
|
+
</div>
|
177
|
+
<div className="testable-test-explorer__item__label__text">
|
178
|
+
{suite.id}
|
179
|
+
</div>
|
180
|
+
<div className="mapping-test-explorer__item__actions">
|
181
|
+
<button
|
182
|
+
className="mapping-test-explorer__item__action mapping-test-explorer__run-test-btn"
|
183
|
+
onClick={runSuite}
|
184
|
+
disabled={isRunning}
|
185
|
+
tabIndex={-1}
|
186
|
+
title={`Run ${suite.id}`}
|
187
|
+
>
|
188
|
+
{<PlayIcon />}
|
189
|
+
</button>
|
190
|
+
</div>
|
191
|
+
</button>
|
192
|
+
</ContextMenu>
|
193
|
+
);
|
194
|
+
},
|
195
|
+
);
|
196
|
+
|
197
|
+
const FunctionTestDataStateEditor = observer(
|
198
|
+
(props: {
|
199
|
+
functionTestSuiteState: FunctionTestSuiteState;
|
200
|
+
storeTestDataState: FunctionStoreTestDataState;
|
201
|
+
}) => {
|
202
|
+
const { functionTestSuiteState, storeTestDataState } = props;
|
203
|
+
const functionTestableState = functionTestSuiteState.functionTestableState;
|
204
|
+
const isReadOnly = functionTestableState.functionEditorState.isReadOnly;
|
205
|
+
const embeddedState = storeTestDataState.embeddedEditorState;
|
206
|
+
const currentData = embeddedState.embeddedData;
|
207
|
+
const isUsingReference = currentData instanceof DataElementReference;
|
208
|
+
const open = (): void => storeTestDataState.setDataElementModal(true);
|
209
|
+
const close = (): void => storeTestDataState.setDataElementModal(false);
|
210
|
+
const changeToUseMyOwn = (): void => {
|
211
|
+
if (isUsingReference) {
|
212
|
+
const newBare = returnUndefOnError(() =>
|
213
|
+
currentData.accept_EmbeddedDataVisitor(
|
214
|
+
new EmbeddedDataCreatorFromEmbeddedData(
|
215
|
+
functionTestableState.editorStore,
|
216
|
+
),
|
217
|
+
),
|
218
|
+
);
|
219
|
+
if (newBare) {
|
220
|
+
storeTestDataState.changeEmbeddedData(newBare);
|
221
|
+
}
|
222
|
+
}
|
223
|
+
};
|
224
|
+
|
225
|
+
const sharedDataHandler = (val: DataElement): void => {
|
226
|
+
const dataRef = new DataElementReference();
|
227
|
+
dataRef.dataElement = PackageableElementExplicitReference.create(val);
|
228
|
+
const dataElementValue = val.data;
|
229
|
+
let embeddedData: EmbeddedData = dataRef;
|
230
|
+
if (
|
231
|
+
currentData instanceof ModelStoreData &&
|
232
|
+
dataElementValue instanceof ExternalFormatData
|
233
|
+
) {
|
234
|
+
const modelStoreVal = currentData.modelData?.[0];
|
235
|
+
if (modelStoreVal instanceof ModelEmbeddedData) {
|
236
|
+
const newModelEmbeddedData = new ModelEmbeddedData();
|
237
|
+
newModelEmbeddedData.model =
|
238
|
+
PackageableElementExplicitReference.create(
|
239
|
+
modelStoreVal.model.value,
|
240
|
+
);
|
241
|
+
|
242
|
+
newModelEmbeddedData.data = dataRef;
|
243
|
+
const modelStoreData = new ModelStoreData();
|
244
|
+
modelStoreData.modelData = [newModelEmbeddedData];
|
245
|
+
embeddedData = modelStoreData;
|
246
|
+
}
|
247
|
+
}
|
248
|
+
storeTestDataState.changeEmbeddedData(embeddedData);
|
249
|
+
};
|
250
|
+
|
251
|
+
const dataElements =
|
252
|
+
functionTestSuiteState.editorStore.graphManagerState.graph.dataElements;
|
253
|
+
|
254
|
+
const filter = (val: DataElement): boolean => {
|
255
|
+
const dataElementData = val.data;
|
256
|
+
if (currentData instanceof RelationalCSVData) {
|
257
|
+
if (dataElementData instanceof RelationalCSVData) {
|
258
|
+
return true;
|
259
|
+
}
|
260
|
+
return false;
|
261
|
+
} else if (currentData instanceof ModelStoreData) {
|
262
|
+
if (
|
263
|
+
dataElementData instanceof ExternalFormatData ||
|
264
|
+
dataElementData instanceof ModelStoreData
|
265
|
+
) {
|
266
|
+
return true;
|
267
|
+
}
|
268
|
+
return false;
|
269
|
+
}
|
270
|
+
return true;
|
271
|
+
};
|
272
|
+
return (
|
273
|
+
<div className="service-test-data-editor">
|
274
|
+
<div className="service-test-suite-editor__header">
|
275
|
+
<div className="service-test-suite-editor__header__title">
|
276
|
+
<div className="service-test-suite-editor__header__title__label">
|
277
|
+
input data
|
278
|
+
</div>
|
279
|
+
</div>
|
280
|
+
<div className="panel__header__actions">
|
281
|
+
{isUsingReference ? (
|
282
|
+
<button
|
283
|
+
className="panel__header__action service-execution-editor__test-data__generate-btn"
|
284
|
+
onClick={changeToUseMyOwn}
|
285
|
+
disabled={!isUsingReference}
|
286
|
+
title="Use own data"
|
287
|
+
tabIndex={-1}
|
288
|
+
>
|
289
|
+
<div className="service-execution-editor__test-data__generate-btn__label">
|
290
|
+
<div className="service-execution-editor__test-data__generate-btn__label__title">
|
291
|
+
Own Data
|
292
|
+
</div>
|
293
|
+
</div>
|
294
|
+
</button>
|
295
|
+
) : (
|
296
|
+
<button
|
297
|
+
className="panel__header__action service-execution-editor__test-data__generate-btn"
|
298
|
+
onClick={open}
|
299
|
+
title="Use Shared Data via Defined Data Element"
|
300
|
+
disabled={!dataElements.length}
|
301
|
+
tabIndex={-1}
|
302
|
+
>
|
303
|
+
<div className="service-execution-editor__test-data__generate-btn__label">
|
304
|
+
<div className="service-execution-editor__test-data__generate-btn__label__title">
|
305
|
+
Shared Data
|
306
|
+
</div>
|
307
|
+
</div>
|
308
|
+
</button>
|
309
|
+
)}
|
310
|
+
</div>
|
311
|
+
</div>
|
312
|
+
|
313
|
+
{storeTestDataState.dataElementModal && (
|
314
|
+
<SharedDataElementModal
|
315
|
+
isReadOnly={false}
|
316
|
+
editorStore={storeTestDataState.editorStore}
|
317
|
+
close={close}
|
318
|
+
filterBy={filter}
|
319
|
+
handler={sharedDataHandler}
|
320
|
+
/>
|
321
|
+
)}
|
322
|
+
<EmbeddedDataEditor
|
323
|
+
isReadOnly={isReadOnly}
|
324
|
+
embeddedDataEditorState={storeTestDataState.embeddedEditorState}
|
325
|
+
/>
|
326
|
+
</div>
|
327
|
+
);
|
328
|
+
},
|
329
|
+
);
|
330
|
+
|
331
|
+
const FunctionTestEditor = observer(
|
332
|
+
(props: { functionTestState: FunctionTestState }) => {
|
333
|
+
const { functionTestState } = props;
|
334
|
+
const mappingTest = functionTestState.test;
|
335
|
+
return (
|
336
|
+
<div className="service-test-editor panel">
|
337
|
+
<div className="panel mapping-testable-editor">
|
338
|
+
<div className="mapping-testable-editor__content">
|
339
|
+
<ResizablePanelGroup orientation="horizontal">
|
340
|
+
<ResizablePanel size={120}>
|
341
|
+
<div className="service-test-data-editor panel">
|
342
|
+
<div className="service-test-editor__setup__configuration">
|
343
|
+
<div className="panel__content__form__section">
|
344
|
+
<div className="panel__content__form__section__header__label">
|
345
|
+
Test Documentation
|
346
|
+
</div>
|
347
|
+
<textarea
|
348
|
+
className="panel__content__form__section__textarea mapping-testable-editor__doc__textarea"
|
349
|
+
spellCheck={false}
|
350
|
+
value={mappingTest.doc ?? ''}
|
351
|
+
onChange={(event) => {
|
352
|
+
atomicTest_setDoc(
|
353
|
+
mappingTest,
|
354
|
+
event.target.value ? event.target.value : undefined,
|
355
|
+
);
|
356
|
+
}}
|
357
|
+
/>
|
358
|
+
</div>
|
359
|
+
</div>
|
360
|
+
</div>
|
361
|
+
</ResizablePanel>
|
362
|
+
<ResizablePanelSplitter>
|
363
|
+
<ResizablePanelSplitterLine color="var(--color-dark-grey-200)" />
|
364
|
+
</ResizablePanelSplitter>
|
365
|
+
<ResizablePanel>
|
366
|
+
{functionTestState.selectedAsertionState && (
|
367
|
+
<TestAssertionEditor
|
368
|
+
testAssertionState={functionTestState.selectedAsertionState}
|
369
|
+
/>
|
370
|
+
)}
|
371
|
+
</ResizablePanel>
|
372
|
+
</ResizablePanelGroup>
|
373
|
+
</div>
|
374
|
+
</div>
|
375
|
+
</div>
|
376
|
+
);
|
377
|
+
},
|
378
|
+
);
|
379
|
+
|
380
|
+
const FunctionTestItem = observer(
|
381
|
+
(props: {
|
382
|
+
suiteState: FunctionTestSuiteState;
|
383
|
+
functionTestState: FunctionTestState;
|
384
|
+
}) => {
|
385
|
+
const { functionTestState, suiteState } = props;
|
386
|
+
const mappingTest = functionTestState.test;
|
387
|
+
const isRunning = functionTestState.runningTestAction.isInProgress;
|
388
|
+
const [isSelectedFromContextMenu, setIsSelectedFromContextMenu] =
|
389
|
+
useState(false);
|
390
|
+
const isReadOnly =
|
391
|
+
suiteState.functionTestableState.functionEditorState.isReadOnly;
|
392
|
+
const openTest = (): void => suiteState.changeTest(mappingTest);
|
393
|
+
const isActive = suiteState.selectTestState?.test === mappingTest;
|
394
|
+
const _testableResult = getTestableResultFromTestResult(
|
395
|
+
functionTestState.testResultState.result,
|
396
|
+
);
|
397
|
+
|
398
|
+
const testableResult = isRunning
|
399
|
+
? TESTABLE_RESULT.IN_PROGRESS
|
400
|
+
: _testableResult;
|
401
|
+
const resultIcon = getTestableResultIcon(testableResult);
|
402
|
+
const onContextMenuOpen = (): void => setIsSelectedFromContextMenu(true);
|
403
|
+
const onContextMenuClose = (): void => setIsSelectedFromContextMenu(false);
|
404
|
+
const add = (): void => {
|
405
|
+
// TODO
|
406
|
+
};
|
407
|
+
const _delete = (): void => {
|
408
|
+
suiteState.deleteTest(mappingTest);
|
409
|
+
};
|
410
|
+
|
411
|
+
const rename = (): void => {
|
412
|
+
// suiteState.mappingTestableState.setRenameComponent(mappingTest);
|
413
|
+
};
|
414
|
+
const runTest = (): void => {
|
415
|
+
flowResult(functionTestState.runTest()).catch(
|
416
|
+
functionTestState.editorStore.applicationStore.alertUnhandledError,
|
417
|
+
);
|
418
|
+
};
|
419
|
+
return (
|
420
|
+
<ContextMenu
|
421
|
+
className={clsx(
|
422
|
+
'testable-test-explorer__item',
|
423
|
+
{
|
424
|
+
'testable-test-explorer__item--selected-from-context-menu':
|
425
|
+
!isActive && isSelectedFromContextMenu,
|
426
|
+
},
|
427
|
+
{ 'testable-test-explorer__item--active': isActive },
|
428
|
+
)}
|
429
|
+
disabled={isReadOnly}
|
430
|
+
content={
|
431
|
+
<FunctionTestableContextMenu
|
432
|
+
addName="Test"
|
433
|
+
add={add}
|
434
|
+
_delete={_delete}
|
435
|
+
rename={rename}
|
436
|
+
/>
|
437
|
+
}
|
438
|
+
menuProps={{ elevation: 7 }}
|
439
|
+
onOpen={onContextMenuOpen}
|
440
|
+
onClose={onContextMenuClose}
|
441
|
+
>
|
442
|
+
<button
|
443
|
+
className={clsx('testable-test-explorer__item__label')}
|
444
|
+
onClick={openTest}
|
445
|
+
tabIndex={-1}
|
446
|
+
>
|
447
|
+
<div className="testable-test-explorer__item__label__icon">
|
448
|
+
{resultIcon}
|
449
|
+
</div>
|
450
|
+
<div className="testable-test-explorer__item__label__text">
|
451
|
+
{mappingTest.id}
|
452
|
+
</div>
|
453
|
+
<div className="mapping-test-explorer__item__actions">
|
454
|
+
<button
|
455
|
+
className="mapping-test-explorer__item__action mapping-test-explorer__run-test-btn"
|
456
|
+
onClick={runTest}
|
457
|
+
disabled={functionTestState.runningTestAction.isInProgress}
|
458
|
+
tabIndex={-1}
|
459
|
+
title={`Run ${functionTestState.test.id}`}
|
460
|
+
>
|
461
|
+
{<PlayIcon />}
|
462
|
+
</button>
|
463
|
+
</div>
|
464
|
+
</button>
|
465
|
+
</ContextMenu>
|
466
|
+
);
|
467
|
+
},
|
468
|
+
);
|
469
|
+
|
470
|
+
const FunctionTestSuiteEditor = observer(
|
471
|
+
(props: { functionTestSuiteState: FunctionTestSuiteState }) => {
|
472
|
+
const { functionTestSuiteState } = props;
|
473
|
+
const dataState = functionTestSuiteState.dataState;
|
474
|
+
const editorStore = functionTestSuiteState.editorStore;
|
475
|
+
const selectedTestState = functionTestSuiteState.selectTestState;
|
476
|
+
const addTest = (): void => {
|
477
|
+
// TODO
|
478
|
+
};
|
479
|
+
const runTests = (): void => {
|
480
|
+
flowResult(functionTestSuiteState.runSuite()).catch(
|
481
|
+
editorStore.applicationStore.alertUnhandledError,
|
482
|
+
);
|
483
|
+
};
|
484
|
+
const runFailingTests = (): void => {
|
485
|
+
flowResult(functionTestSuiteState.runFailingTests()).catch(
|
486
|
+
editorStore.applicationStore.alertUnhandledError,
|
487
|
+
);
|
488
|
+
};
|
489
|
+
|
490
|
+
const addStoreTestData = (): void => {
|
491
|
+
// mappingTestableDataState.setShowModal(true);
|
492
|
+
};
|
493
|
+
|
494
|
+
const renderMappingTestEditor = (): React.ReactNode => {
|
495
|
+
if (selectedTestState) {
|
496
|
+
return <FunctionTestEditor functionTestState={selectedTestState} />;
|
497
|
+
} else if (!functionTestSuiteState.suite.tests.length) {
|
498
|
+
return (
|
499
|
+
<BlankPanelPlaceholder
|
500
|
+
text="Add Function Test"
|
501
|
+
onClick={addTest}
|
502
|
+
clickActionType="add"
|
503
|
+
tooltipText="Click to add function test"
|
504
|
+
/>
|
505
|
+
);
|
506
|
+
}
|
507
|
+
return null;
|
508
|
+
};
|
509
|
+
return (
|
510
|
+
<ResizablePanelGroup orientation="horizontal">
|
511
|
+
<ResizablePanel size={300} minSize={28}>
|
512
|
+
<div className="service-test-data-editor panel">
|
513
|
+
{functionTestSuiteState.dataState.dataHolder.testData?.length ? (
|
514
|
+
<>
|
515
|
+
{dataState.selectedDataState && (
|
516
|
+
<FunctionTestDataStateEditor
|
517
|
+
functionTestSuiteState={functionTestSuiteState}
|
518
|
+
storeTestDataState={dataState.selectedDataState}
|
519
|
+
/>
|
520
|
+
)}
|
521
|
+
</>
|
522
|
+
) : (
|
523
|
+
<BlankPanelPlaceholder
|
524
|
+
text="Add Store Test Data"
|
525
|
+
onClick={addStoreTestData}
|
526
|
+
clickActionType="add"
|
527
|
+
tooltipText="Click to add store test data"
|
528
|
+
/>
|
529
|
+
)}
|
530
|
+
{/* {mappingTestableDataState.showNewModal && (
|
531
|
+
<CreateStoreTestDataModal mappingTestState={mappingTestState} />
|
532
|
+
)} */}
|
533
|
+
</div>
|
534
|
+
</ResizablePanel>
|
535
|
+
<ResizablePanelSplitter>
|
536
|
+
<ResizablePanelSplitterLine color="var(--color-dark-grey-200)" />
|
537
|
+
</ResizablePanelSplitter>
|
538
|
+
<ResizablePanel minSize={56}>
|
539
|
+
<ResizablePanelGroup orientation="vertical">
|
540
|
+
<ResizablePanel size={200} minSize={28}>
|
541
|
+
<div className="binding-editor__header">
|
542
|
+
<div className="binding-editor__header__title">
|
543
|
+
<div className="panel__header__title__content">Tests</div>
|
544
|
+
</div>
|
545
|
+
<div className="panel__header__actions">
|
546
|
+
<button
|
547
|
+
className="panel__header__action testable-test-explorer__play__all__icon"
|
548
|
+
tabIndex={-1}
|
549
|
+
onClick={runTests}
|
550
|
+
title="Run All Tests"
|
551
|
+
>
|
552
|
+
<RunAllIcon />
|
553
|
+
</button>
|
554
|
+
<button
|
555
|
+
className="panel__header__action testable-test-explorer__play__all__icon"
|
556
|
+
tabIndex={-1}
|
557
|
+
onClick={runFailingTests}
|
558
|
+
title="Run All Failing Tests"
|
559
|
+
>
|
560
|
+
<RunErrorsIcon />
|
561
|
+
</button>
|
562
|
+
<button
|
563
|
+
className="panel__header__action"
|
564
|
+
tabIndex={-1}
|
565
|
+
onClick={addTest}
|
566
|
+
title="Add Mapping Test"
|
567
|
+
>
|
568
|
+
<PlusIcon />
|
569
|
+
</button>
|
570
|
+
</div>
|
571
|
+
</div>
|
572
|
+
<PanelContent>
|
573
|
+
{functionTestSuiteState.testStates.map((test) => (
|
574
|
+
<FunctionTestItem
|
575
|
+
key={test.uuid}
|
576
|
+
functionTestState={test}
|
577
|
+
suiteState={functionTestSuiteState}
|
578
|
+
/>
|
579
|
+
))}
|
580
|
+
{/* {mappingTestSuiteState.showCreateModal && (
|
581
|
+
<CreateTestModal mappingSuiteState={mappingTestSuiteState} />
|
582
|
+
)} */}
|
583
|
+
</PanelContent>
|
584
|
+
</ResizablePanel>
|
585
|
+
<ResizablePanelSplitter>
|
586
|
+
<ResizablePanelSplitterLine color="var(--color-dark-grey-200)" />
|
587
|
+
</ResizablePanelSplitter>
|
588
|
+
<ResizablePanel minSize={28}>
|
589
|
+
{renderMappingTestEditor()}
|
590
|
+
</ResizablePanel>
|
591
|
+
</ResizablePanelGroup>
|
592
|
+
</ResizablePanel>
|
593
|
+
</ResizablePanelGroup>
|
594
|
+
);
|
595
|
+
},
|
596
|
+
);
|
597
|
+
|
598
|
+
export const FunctionTestableEditor = observer(
|
599
|
+
(props: { functionTestableState: FunctionTestableState }) => {
|
600
|
+
const { functionTestableState } = props;
|
601
|
+
const suites = functionTestableState.function.tests;
|
602
|
+
const functionEditorState = functionTestableState.functionEditorState;
|
603
|
+
const isReadOnly = functionEditorState.isReadOnly;
|
604
|
+
const selectedSuiteState = functionTestableState.selectedTestSuite;
|
605
|
+
// use effect
|
606
|
+
useEffect(() => {
|
607
|
+
functionTestableState.init();
|
608
|
+
}, [functionTestableState]);
|
609
|
+
|
610
|
+
const runSuites = (): void => {
|
611
|
+
functionTestableState.runTestable();
|
612
|
+
};
|
613
|
+
|
614
|
+
const runFailingTests = (): void => {
|
615
|
+
functionTestableState.runAllFailingSuites();
|
616
|
+
};
|
617
|
+
const addSuite = (): void => {
|
618
|
+
// TODO
|
619
|
+
};
|
620
|
+
|
621
|
+
const renderSuiteState = (): React.ReactNode => {
|
622
|
+
if (selectedSuiteState) {
|
623
|
+
return (
|
624
|
+
<FunctionTestSuiteEditor
|
625
|
+
functionTestSuiteState={selectedSuiteState}
|
626
|
+
/>
|
627
|
+
);
|
628
|
+
} else if (!suites.length) {
|
629
|
+
return (
|
630
|
+
<BlankPanelPlaceholder
|
631
|
+
text="Add Test Suite"
|
632
|
+
onClick={addSuite}
|
633
|
+
clickActionType="add"
|
634
|
+
tooltipText="Click to add test suite"
|
635
|
+
/>
|
636
|
+
);
|
637
|
+
}
|
638
|
+
return null;
|
639
|
+
};
|
640
|
+
|
641
|
+
const renameTestingComponent = (val: string): void => {
|
642
|
+
functionTestableState.renameTestableComponent(val);
|
643
|
+
};
|
644
|
+
useApplicationNavigationContext(
|
645
|
+
LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY.MAPPING_EDITOR_TEST,
|
646
|
+
);
|
647
|
+
|
648
|
+
return (
|
649
|
+
<div className="service-test-suite-editor panel">
|
650
|
+
<div className="service-test-suite-editor">
|
651
|
+
<ResizablePanelGroup orientation="vertical">
|
652
|
+
<ResizablePanel size={200} minSize={28}>
|
653
|
+
<div className="binding-editor__header">
|
654
|
+
<div className="binding-editor__header__title">
|
655
|
+
<div className="panel__header__title__content">
|
656
|
+
Test Suites
|
657
|
+
</div>
|
658
|
+
</div>
|
659
|
+
|
660
|
+
<div className="panel__header__actions">
|
661
|
+
<button
|
662
|
+
className="panel__header__action testable-test-explorer__play__all__icon"
|
663
|
+
tabIndex={-1}
|
664
|
+
onClick={runSuites}
|
665
|
+
title="Run All Suites"
|
666
|
+
>
|
667
|
+
<RunAllIcon />
|
668
|
+
</button>
|
669
|
+
<button
|
670
|
+
className="panel__header__action testable-test-explorer__play__all__icon"
|
671
|
+
tabIndex={-1}
|
672
|
+
onClick={runFailingTests}
|
673
|
+
title="Run All Failing Tests"
|
674
|
+
>
|
675
|
+
<RunErrorsIcon />
|
676
|
+
</button>
|
677
|
+
<button
|
678
|
+
className="panel__header__action"
|
679
|
+
tabIndex={-1}
|
680
|
+
onClick={addSuite}
|
681
|
+
title="Add Function Suite"
|
682
|
+
>
|
683
|
+
<PlusIcon />
|
684
|
+
</button>
|
685
|
+
</div>
|
686
|
+
</div>
|
687
|
+
<PanelContent>
|
688
|
+
{suites.map((suite) => (
|
689
|
+
<FunctionTestSuiteItem
|
690
|
+
key={suite.id}
|
691
|
+
functionTestableState={functionTestableState}
|
692
|
+
suite={suite}
|
693
|
+
/>
|
694
|
+
))}
|
695
|
+
{!suites.length && (
|
696
|
+
<BlankPanelPlaceholder
|
697
|
+
text="Add Test Suite"
|
698
|
+
onClick={addSuite}
|
699
|
+
clickActionType="add"
|
700
|
+
tooltipText="Click to add test suite"
|
701
|
+
/>
|
702
|
+
)}
|
703
|
+
</PanelContent>
|
704
|
+
{!suites.length && (
|
705
|
+
<BlankPanelPlaceholder
|
706
|
+
disabled={functionEditorState.isReadOnly}
|
707
|
+
onClick={addSuite}
|
708
|
+
text="Add a Test Suite"
|
709
|
+
clickActionType="add"
|
710
|
+
tooltipText="Click to add a new function test suite"
|
711
|
+
/>
|
712
|
+
)}
|
713
|
+
</ResizablePanel>
|
714
|
+
<ResizablePanelSplitter>
|
715
|
+
<ResizablePanelSplitterLine color="var(--color-dark-grey-200)" />
|
716
|
+
</ResizablePanelSplitter>
|
717
|
+
<ResizablePanel minSize={56}>
|
718
|
+
<div className="panel mapping-testable-editorr">
|
719
|
+
<div className="mapping-testable-editor__content">
|
720
|
+
{renderSuiteState()}
|
721
|
+
</div>
|
722
|
+
</div>
|
723
|
+
</ResizablePanel>
|
724
|
+
</ResizablePanelGroup>
|
725
|
+
{/* {mappingTestableState.createSuiteState && (
|
726
|
+
<CreateTestSuiteModal
|
727
|
+
creatorState={mappingTestableState.createSuiteState}
|
728
|
+
/>
|
729
|
+
)} */}
|
730
|
+
{functionTestableState.testableComponentToRename && (
|
731
|
+
<RenameModal
|
732
|
+
val={functionTestableState.testableComponentToRename.id}
|
733
|
+
isReadOnly={isReadOnly}
|
734
|
+
showModal={true}
|
735
|
+
closeModal={(): void =>
|
736
|
+
functionTestableState.setRenameComponent(undefined)
|
737
|
+
}
|
738
|
+
setValue={(val: string): void => renameTestingComponent(val)}
|
739
|
+
errorMessageFunc={(_val: string | undefined) =>
|
740
|
+
validateTestableId(_val, undefined)
|
741
|
+
}
|
742
|
+
/>
|
743
|
+
)}
|
744
|
+
</div>
|
745
|
+
</div>
|
746
|
+
);
|
747
|
+
},
|
748
|
+
);
|