@finos/legend-application-studio 28.21.23 → 28.21.25
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__/LegendStudioDocumentation.d.ts +2 -2
- package/lib/__lib__/LegendStudioDocumentation.d.ts.map +1 -1
- package/lib/__lib__/LegendStudioDocumentation.js +1 -1
- package/lib/__lib__/LegendStudioDocumentation.js.map +1 -1
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.js +2 -5
- package/lib/components/editor/editor-group/data-editor/RelationElementsDataEditor.js.map +1 -1
- package/lib/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.js +13 -239
- package/lib/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.js.map +1 -1
- package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.js +17 -3
- package/lib/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.js.map +1 -1
- package/lib/components/editor/editor-group/ingest-editor/testable/IngestTestableEditor.d.ts +22 -0
- package/lib/components/editor/editor-group/ingest-editor/testable/IngestTestableEditor.d.ts.map +1 -0
- package/lib/components/editor/editor-group/ingest-editor/testable/IngestTestableEditor.js +134 -0
- package/lib/components/editor/editor-group/ingest-editor/testable/IngestTestableEditor.js.map +1 -0
- package/lib/components/editor/editor-group/testable/LakehouseTestableEditor.d.ts +89 -0
- package/lib/components/editor/editor-group/testable/LakehouseTestableEditor.d.ts.map +1 -0
- package/lib/components/editor/editor-group/testable/LakehouseTestableEditor.js +144 -0
- package/lib/components/editor/editor-group/testable/LakehouseTestableEditor.js.map +1 -0
- package/lib/components/editor/editor-group/testable/TestableSharedComponents.d.ts.map +1 -1
- package/lib/components/editor/editor-group/testable/TestableSharedComponents.js +14 -8
- package/lib/components/editor/editor-group/testable/TestableSharedComponents.js.map +1 -1
- package/lib/components/editor/ingest-definition-editor.css +1 -1
- package/lib/components/editor/ingest-definition-editor.css.map +1 -1
- package/lib/components/project-reviewer/ProjectReviewer.d.ts.map +1 -1
- package/lib/components/project-reviewer/ProjectReviewer.js +2 -1
- package/lib/components/project-reviewer/ProjectReviewer.js.map +1 -1
- package/lib/components/project-view/ProjectViewer.d.ts.map +1 -1
- package/lib/components/project-view/ProjectViewer.js +2 -2
- package/lib/components/project-view/ProjectViewer.js.map +1 -1
- package/lib/components/showcase/ShowcaseViewer.d.ts.map +1 -1
- package/lib/components/showcase/ShowcaseViewer.js +2 -2
- package/lib/components/showcase/ShowcaseViewer.js.map +1 -1
- package/lib/components/workspace-setup/WorkspaceSetup.d.ts +1 -1
- package/lib/components/workspace-setup/WorkspaceSetup.d.ts.map +1 -1
- package/lib/components/workspace-setup/WorkspaceSetup.js +98 -43
- package/lib/components/workspace-setup/WorkspaceSetup.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.js +1 -2
- package/lib/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.d.ts +8 -30
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.js +7 -147
- package/lib/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.js +32 -28
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.d.ts +8 -0
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.js +15 -0
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestTestableState.d.ts +86 -0
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestTestableState.d.ts.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestTestableState.js +420 -0
- package/lib/stores/editor/editor-state/element-editor-state/ingest/IngestTestableState.js.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/testable/LakehouseTestableUtils.d.ts +62 -0
- package/lib/stores/editor/editor-state/element-editor-state/testable/LakehouseTestableUtils.d.ts.map +1 -0
- package/lib/stores/editor/editor-state/element-editor-state/testable/LakehouseTestableUtils.js +138 -0
- package/lib/stores/editor/editor-state/element-editor-state/testable/LakehouseTestableUtils.js.map +1 -0
- package/lib/stores/workspace-setup/WorkspaceSetupStore.d.ts +10 -1
- package/lib/stores/workspace-setup/WorkspaceSetupStore.d.ts.map +1 -1
- package/lib/stores/workspace-setup/WorkspaceSetupStore.js +105 -12
- package/lib/stores/workspace-setup/WorkspaceSetupStore.js.map +1 -1
- package/package.json +11 -11
- package/src/__lib__/LegendStudioDocumentation.ts +1 -1
- package/src/components/editor/editor-group/data-editor/RelationElementsDataEditor.tsx +2 -5
- package/src/components/editor/editor-group/dataProduct/testable/DataProductTestableEditor.tsx +19 -869
- package/src/components/editor/editor-group/ingest-editor/IngestDefinitionEditor.tsx +90 -34
- package/src/components/editor/editor-group/ingest-editor/testable/IngestTestableEditor.tsx +418 -0
- package/src/components/editor/editor-group/testable/LakehouseTestableEditor.tsx +564 -0
- package/src/components/editor/editor-group/testable/TestableSharedComponents.tsx +17 -9
- package/src/components/project-reviewer/ProjectReviewer.tsx +2 -0
- package/src/components/project-view/ProjectViewer.tsx +2 -1
- package/src/components/showcase/ShowcaseViewer.tsx +2 -1
- package/src/components/workspace-setup/WorkspaceSetup.tsx +169 -75
- package/src/stores/editor/editor-state/element-editor-state/data/EmbeddedDataState.ts +1 -2
- package/src/stores/editor/editor-state/element-editor-state/dataProduct/DataProductEditorState.ts +1 -0
- package/src/stores/editor/editor-state/element-editor-state/dataProduct/testable/DataProductTestableState.ts +18 -204
- package/src/stores/editor/editor-state/element-editor-state/function-activator/testable/FunctionTestableState.ts +41 -36
- package/src/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.ts +16 -0
- package/src/stores/editor/editor-state/element-editor-state/ingest/IngestTestableState.ts +654 -0
- package/src/stores/editor/editor-state/element-editor-state/testable/LakehouseTestableUtils.ts +224 -0
- package/src/stores/workspace-setup/WorkspaceSetupStore.ts +125 -8
- package/tsconfig.json +4 -0
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
type PackageableElement,
|
|
21
21
|
type TestSuite,
|
|
22
22
|
type RawLambda,
|
|
23
|
-
type AccessorOwner,
|
|
24
23
|
type ValueSpecification,
|
|
25
24
|
DataProduct,
|
|
26
25
|
FunctionAccessPoint,
|
|
@@ -46,9 +45,7 @@ import {
|
|
|
46
45
|
observe_DataProductTestSuite,
|
|
47
46
|
observe_ValueSpecification,
|
|
48
47
|
buildLambdaVariableExpressions,
|
|
49
|
-
IngestDefinition,
|
|
50
|
-
getAccessorItemLabelForElement,
|
|
51
|
-
type AbstractPureGraphManager,
|
|
48
|
+
type IngestDefinition,
|
|
52
49
|
} from '@finos/legend-graph';
|
|
53
50
|
import {
|
|
54
51
|
type GeneratorFn,
|
|
@@ -73,10 +70,7 @@ import {
|
|
|
73
70
|
} from 'mobx';
|
|
74
71
|
import type { EditorStore } from '../../../../EditorStore.js';
|
|
75
72
|
import type { DataProductEditorState } from '../DataProductEditorState.js';
|
|
76
|
-
import {
|
|
77
|
-
RelationElementsDataState,
|
|
78
|
-
RelationElementState,
|
|
79
|
-
} from '../../data/EmbeddedDataState.js';
|
|
73
|
+
import { RelationElementState } from '../../data/EmbeddedDataState.js';
|
|
80
74
|
import { TESTABLE_RESULT } from '../../../../sidebar-state/testable/GlobalTestRunnerState.js';
|
|
81
75
|
import { testSuite_addTest } from '../../../../../graph-modifier/Testable_GraphModifierHelper.js';
|
|
82
76
|
import {
|
|
@@ -84,19 +78,16 @@ import {
|
|
|
84
78
|
TestableTestSuiteEditorState,
|
|
85
79
|
} from '../../testable/TestableEditorState.js';
|
|
86
80
|
import { generateVariableExpressionMockValue } from '@finos/legend-query-builder';
|
|
81
|
+
import {
|
|
82
|
+
buildRelationElementsDataWithColumns,
|
|
83
|
+
createEmptyRelationElement,
|
|
84
|
+
isIngestOrDataProductAccessor,
|
|
85
|
+
LakehouseElementTestDataState,
|
|
86
|
+
} from '../../testable/LakehouseTestableUtils.js';
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
): RelationElement => {
|
|
92
|
-
const row = observe_RelationRowTestData(new RelationRowTestData());
|
|
93
|
-
row.values = columns.map(() => '');
|
|
94
|
-
const relationElement = new RelationElement();
|
|
95
|
-
relationElement.paths = [itemId];
|
|
96
|
-
relationElement.columns = columns;
|
|
97
|
-
relationElement.rows = [row];
|
|
98
|
-
return observe_RelationElement(relationElement);
|
|
99
|
-
};
|
|
88
|
+
export type { LakehouseElementTestDataState as DataProductElementTestDataState };
|
|
89
|
+
|
|
90
|
+
// ─── Data-product-specific helpers ───────────────────────────────────────────
|
|
100
91
|
|
|
101
92
|
/**
|
|
102
93
|
* Returns the lambda for an access point (handles both LakehouseAccessPoint
|
|
@@ -111,59 +102,9 @@ const getAccessPointLambda = (
|
|
|
111
102
|
? accessPoint.query
|
|
112
103
|
: undefined;
|
|
113
104
|
|
|
114
|
-
/**
|
|
115
|
-
* Builds a RelationElementsData from resolved accessors using the accessor
|
|
116
|
-
* relation type as the source of truth for column definitions.
|
|
117
|
-
*/
|
|
118
|
-
const buildRelationElementsDataWithColumns = (
|
|
119
|
-
accs: Accessor[],
|
|
120
|
-
): RelationElementsData => {
|
|
121
|
-
const relData = new RelationElementsData();
|
|
122
|
-
relData.relationElements = accs.map((acc) => {
|
|
123
|
-
const itemId = acc.accessor || 'UNKNOWN';
|
|
124
|
-
const columns = acc.relationType.columns.map((column) => column.name);
|
|
125
|
-
return createEmptyRelationElement(itemId, columns);
|
|
126
|
-
});
|
|
127
|
-
return relData;
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
const isIngestOrDataProductAccessor = (
|
|
131
|
-
accessor: Accessor,
|
|
132
|
-
): accessor is Accessor =>
|
|
133
|
-
accessor.parentElement instanceof DataProduct ||
|
|
134
|
-
accessor.parentElement instanceof IngestDefinition;
|
|
135
|
-
|
|
136
105
|
const getAccessPointDisplayLabel = (accessPoint: AccessPoint): string =>
|
|
137
106
|
accessPoint.id;
|
|
138
107
|
|
|
139
|
-
interface ElementDataItem {
|
|
140
|
-
id: string;
|
|
141
|
-
label: string;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const getElementDataItems = (
|
|
145
|
-
element: PackageableElement,
|
|
146
|
-
graphManager: AbstractPureGraphManager,
|
|
147
|
-
): ElementDataItem[] => {
|
|
148
|
-
if (element instanceof DataProduct) {
|
|
149
|
-
return element.accessPointGroups
|
|
150
|
-
.flatMap((g) => g.accessPoints)
|
|
151
|
-
.map((ap) => ({
|
|
152
|
-
id: ap.id,
|
|
153
|
-
label: getAccessPointDisplayLabel(ap),
|
|
154
|
-
}));
|
|
155
|
-
}
|
|
156
|
-
if (element instanceof IngestDefinition) {
|
|
157
|
-
return graphManager
|
|
158
|
-
.getIngestDefinitionDatasetNames(element)
|
|
159
|
-
.map((name) => ({
|
|
160
|
-
id: name,
|
|
161
|
-
label: name,
|
|
162
|
-
}));
|
|
163
|
-
}
|
|
164
|
-
return [];
|
|
165
|
-
};
|
|
166
|
-
|
|
167
108
|
const inferDataProductItemColumns = async (
|
|
168
109
|
editorStore: EditorStore,
|
|
169
110
|
dataProduct: DataProduct,
|
|
@@ -576,119 +517,8 @@ export class DataProductTestState extends TestableTestEditorState {
|
|
|
576
517
|
}
|
|
577
518
|
|
|
578
519
|
// ─── Per-element test data state ─────────────────────────────────────────────
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
readonly testDataState: DataProductTestDataState;
|
|
582
|
-
readonly testData: BaseDataResolver;
|
|
583
|
-
readonly editorStore: EditorStore;
|
|
584
|
-
readonly relationElementsDataState: RelationElementsDataState | undefined;
|
|
585
|
-
|
|
586
|
-
constructor(
|
|
587
|
-
testDataState: DataProductTestDataState,
|
|
588
|
-
testData: BaseDataResolver,
|
|
589
|
-
) {
|
|
590
|
-
this.testDataState = testDataState;
|
|
591
|
-
this.testData = testData;
|
|
592
|
-
this.editorStore = testDataState.editorStore;
|
|
593
|
-
if (testData.data instanceof RelationElementsData) {
|
|
594
|
-
this.relationElementsDataState = new RelationElementsDataState(
|
|
595
|
-
this.editorStore,
|
|
596
|
-
testData.data,
|
|
597
|
-
);
|
|
598
|
-
this.initAccessorOptions();
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
get element(): PackageableElement {
|
|
603
|
-
return this.testData.element.value;
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
get elementName(): string {
|
|
607
|
-
return this.testData.element.value.name;
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
get itemLabel(): string {
|
|
611
|
-
return getAccessorItemLabelForElement(this.element as AccessorOwner);
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
private initAccessorOptions(): void {
|
|
615
|
-
const dataState = this.relationElementsDataState;
|
|
616
|
-
if (!dataState) {
|
|
617
|
-
return;
|
|
618
|
-
}
|
|
619
|
-
this.refreshAccessorOptions(dataState).catch(noop);
|
|
620
|
-
dataState.setRefreshAccessorOptions(() =>
|
|
621
|
-
this.refreshAccessorOptions(dataState),
|
|
622
|
-
);
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
private async refreshAccessorOptions(
|
|
626
|
-
dataState: RelationElementsDataState,
|
|
627
|
-
): Promise<void> {
|
|
628
|
-
const element = this.element;
|
|
629
|
-
const graphManager = this.editorStore.graphManagerState.graphManager;
|
|
630
|
-
const graph = this.editorStore.graphManagerState.graph;
|
|
631
|
-
const items = getElementDataItems(element, graphManager);
|
|
632
|
-
if (items.length === 0) {
|
|
633
|
-
dataState.setAccessorOptions(undefined, undefined);
|
|
634
|
-
return;
|
|
635
|
-
}
|
|
636
|
-
const typeLabel = this.itemLabel;
|
|
637
|
-
const options = await Promise.all(
|
|
638
|
-
items.map(async (item) => {
|
|
639
|
-
let columns: string[] = [];
|
|
640
|
-
try {
|
|
641
|
-
if (element instanceof IngestDefinition) {
|
|
642
|
-
const accessor =
|
|
643
|
-
await graphManager.createAccessorFromPackageableElement(
|
|
644
|
-
element,
|
|
645
|
-
graph,
|
|
646
|
-
{ schemaName: undefined, tableName: item.id },
|
|
647
|
-
);
|
|
648
|
-
if (accessor) {
|
|
649
|
-
columns = accessor.relationType.columns.map((c) => c.name);
|
|
650
|
-
}
|
|
651
|
-
} else if (element instanceof DataProduct) {
|
|
652
|
-
const accessor = await graphManager.buildDataProductAccessor(
|
|
653
|
-
element,
|
|
654
|
-
graph,
|
|
655
|
-
{ tableName: item.id },
|
|
656
|
-
);
|
|
657
|
-
if (accessor) {
|
|
658
|
-
columns = accessor.relationType.columns.map((c) => c.name);
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
} catch {
|
|
662
|
-
// best-effort column resolution
|
|
663
|
-
}
|
|
664
|
-
return {
|
|
665
|
-
label: item.label,
|
|
666
|
-
value: item.id,
|
|
667
|
-
columns,
|
|
668
|
-
};
|
|
669
|
-
}),
|
|
670
|
-
);
|
|
671
|
-
runInAction(() => {
|
|
672
|
-
dataState.setAccessorOptions(options, typeLabel);
|
|
673
|
-
// Back-fill columns on existing relation elements that have none
|
|
674
|
-
const columnsByItem = new Map(
|
|
675
|
-
options
|
|
676
|
-
.filter((o) => o.columns.length > 0)
|
|
677
|
-
.map((o) => [o.value, o.columns]),
|
|
678
|
-
);
|
|
679
|
-
for (const relState of dataState.relationElementStates) {
|
|
680
|
-
const rel = relState.relationElement;
|
|
681
|
-
if (rel.columns.length === 0) {
|
|
682
|
-
const key = rel.paths[rel.paths.length - 1];
|
|
683
|
-
const cols = key ? columnsByItem.get(key) : undefined;
|
|
684
|
-
if (cols) {
|
|
685
|
-
rel.columns = cols;
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
});
|
|
690
|
-
}
|
|
691
|
-
}
|
|
520
|
+
// Replaced by the shared LakehouseElementTestDataState from LakehouseTestableUtils.
|
|
521
|
+
// The type alias above maintains backward compatibility for any existing imports.
|
|
692
522
|
|
|
693
523
|
// ─── Test data state for a suite ─────────────────────────────────────────────
|
|
694
524
|
|
|
@@ -696,8 +526,8 @@ export class DataProductTestDataState {
|
|
|
696
526
|
readonly editorStore: EditorStore;
|
|
697
527
|
readonly suiteState: DataProductTestSuiteState;
|
|
698
528
|
|
|
699
|
-
elementTestDataStates:
|
|
700
|
-
selectedElementTestDataState:
|
|
529
|
+
elementTestDataStates: LakehouseElementTestDataState[] = [];
|
|
530
|
+
selectedElementTestDataState: LakehouseElementTestDataState | undefined;
|
|
701
531
|
showAddElementModal = false;
|
|
702
532
|
|
|
703
533
|
constructor(
|
|
@@ -765,7 +595,7 @@ export class DataProductTestDataState {
|
|
|
765
595
|
this.refreshElementTestDataStates({ selectedElementPath: path });
|
|
766
596
|
}
|
|
767
597
|
|
|
768
|
-
deleteElement(elementState:
|
|
598
|
+
deleteElement(elementState: LakehouseElementTestDataState): void {
|
|
769
599
|
const suite = this.suiteState.suite;
|
|
770
600
|
if (suite.testData) {
|
|
771
601
|
const idx = suite.testData.indexOf(elementState.testData);
|
|
@@ -783,7 +613,7 @@ export class DataProductTestDataState {
|
|
|
783
613
|
const suite = this.suiteState.suite;
|
|
784
614
|
this.elementTestDataStates = (suite.testData ?? [])
|
|
785
615
|
.filter((td): td is BaseDataResolver => td instanceof BaseDataResolver)
|
|
786
|
-
.map((td) => new
|
|
616
|
+
.map((td) => new LakehouseElementTestDataState(td, this.editorStore));
|
|
787
617
|
|
|
788
618
|
this.selectedElementTestDataState =
|
|
789
619
|
this.elementTestDataStates.find(
|
|
@@ -792,7 +622,7 @@ export class DataProductTestDataState {
|
|
|
792
622
|
}
|
|
793
623
|
|
|
794
624
|
setSelectedElementTestDataState(
|
|
795
|
-
val:
|
|
625
|
+
val: LakehouseElementTestDataState | undefined,
|
|
796
626
|
): void {
|
|
797
627
|
this.selectedElementTestDataState = val;
|
|
798
628
|
}
|
|
@@ -1069,10 +899,6 @@ export class DataProductTestableState {
|
|
|
1069
899
|
}
|
|
1070
900
|
}
|
|
1071
901
|
|
|
1072
|
-
/**
|
|
1073
|
-
* Build suite states from the DataProduct.tests array.
|
|
1074
|
-
* Call this on init and after grammar→form roundtrip.
|
|
1075
|
-
*/
|
|
1076
902
|
init(): void {
|
|
1077
903
|
const dp = this.dataProduct;
|
|
1078
904
|
this.suiteStates = dp.tests.map(
|
|
@@ -1081,13 +907,11 @@ export class DataProductTestableState {
|
|
|
1081
907
|
this.selectedSuiteState = this.suiteStates[0];
|
|
1082
908
|
}
|
|
1083
909
|
|
|
1084
|
-
/** Returns all graph ingest elements available in the model. */
|
|
1085
910
|
get availableIngestSources(): IngestDefinition[] {
|
|
1086
911
|
const graph = this.editorStore.graphManagerState.graph;
|
|
1087
912
|
return graph.ingests;
|
|
1088
913
|
}
|
|
1089
914
|
|
|
1090
|
-
/** Access points on the DataProduct being edited (used for test's accessPointId). */
|
|
1091
915
|
get ownAccessPoints(): AccessPoint[] {
|
|
1092
916
|
return this.dataProduct.accessPointGroups.flatMap((g) => g.accessPoints);
|
|
1093
917
|
}
|
|
@@ -1101,12 +925,6 @@ export class DataProductTestableState {
|
|
|
1101
925
|
: accessPointId;
|
|
1102
926
|
}
|
|
1103
927
|
|
|
1104
|
-
/**
|
|
1105
|
-
* Create a new test suite with one initial test on the DataProduct.
|
|
1106
|
-
* Test data is auto-seeded for the selected access point on the current
|
|
1107
|
-
* DataProduct (no element picker required).
|
|
1108
|
-
* Columns are inferred via the engine when possible.
|
|
1109
|
-
*/
|
|
1110
928
|
*createSuite(
|
|
1111
929
|
suiteName: string,
|
|
1112
930
|
testName: string,
|
|
@@ -1119,7 +937,6 @@ export class DataProductTestableState {
|
|
|
1119
937
|
const suite = new DataProductTestSuite();
|
|
1120
938
|
suite.id = suiteName;
|
|
1121
939
|
|
|
1122
|
-
// Try to infer columns from the access-point lambda
|
|
1123
940
|
let inferredColumns: string[] = [];
|
|
1124
941
|
try {
|
|
1125
942
|
const cols = (yield inferDataProductItemColumns(
|
|
@@ -1134,7 +951,6 @@ export class DataProductTestableState {
|
|
|
1134
951
|
// Column inference is best-effort; continue with empty columns
|
|
1135
952
|
}
|
|
1136
953
|
|
|
1137
|
-
// Resolve INPUT sources via the graph (follows function calls, avoids self-refs)
|
|
1138
954
|
const accessPointForSuite = dp.accessPointGroups
|
|
1139
955
|
.flatMap((g) => g.accessPoints)
|
|
1140
956
|
.find((ap) => ap.id === accessPointId);
|
|
@@ -1174,14 +990,12 @@ export class DataProductTestableState {
|
|
|
1174
990
|
suite.testData.push(resolver);
|
|
1175
991
|
}
|
|
1176
992
|
}
|
|
1177
|
-
// If no external sources were resolved, notify the user and leave test data empty
|
|
1178
993
|
if (suite.testData.length === 0) {
|
|
1179
994
|
this.editorStore.applicationStore.notificationService.notifyWarning(
|
|
1180
995
|
'Access Point accessors cannot be resolved',
|
|
1181
996
|
);
|
|
1182
997
|
}
|
|
1183
998
|
|
|
1184
|
-
// Create one initial test with EqualToRelation assertion
|
|
1185
999
|
const test = new DataProductAccessPointTest();
|
|
1186
1000
|
test.id = testName;
|
|
1187
1001
|
test.__parent = suite;
|
|
@@ -68,6 +68,7 @@ import {
|
|
|
68
68
|
Database,
|
|
69
69
|
DataProduct,
|
|
70
70
|
IngestDefinition,
|
|
71
|
+
LakehouseRuntime,
|
|
71
72
|
PackageableElementExplicitReference,
|
|
72
73
|
observe_ValueSpecification,
|
|
73
74
|
observe_RelationElementsData,
|
|
@@ -1032,44 +1033,48 @@ export class FunctionTestableState extends TestablePackageableElementEditorState
|
|
|
1032
1033
|
`Function Test Suite Only supports One Runtime at this time. Found ${engineRuntimes.length}`,
|
|
1033
1034
|
);
|
|
1034
1035
|
const engineRuntime = guaranteeNonNullable(engineRuntimes[0]);
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
.
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
'
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
if (store instanceof Database) {
|
|
1060
|
-
const relation = new RelationElementsData();
|
|
1061
|
-
data.element = PackageableElementExplicitReference.create(store);
|
|
1062
|
-
data.data = relation;
|
|
1063
|
-
} else if (store instanceof ModelStore) {
|
|
1064
|
-
const modelStoreData = createBareExternalFormat();
|
|
1065
|
-
data.element = PackageableElementExplicitReference.create(store);
|
|
1066
|
-
data.data = modelStoreData;
|
|
1067
|
-
} else {
|
|
1068
|
-
throw new UnsupportedOperationError(
|
|
1069
|
-
`function test store data does not support store: ${store.path}`,
|
|
1036
|
+
if (!(engineRuntime instanceof LakehouseRuntime)) {
|
|
1037
|
+
assertTrue(
|
|
1038
|
+
!(
|
|
1039
|
+
engineRuntime.connectionStores.length &&
|
|
1040
|
+
engineRuntime.connections.length
|
|
1041
|
+
),
|
|
1042
|
+
`Runtime found has two connection types defined. Please use connection stores only`,
|
|
1043
|
+
);
|
|
1044
|
+
const stores = [
|
|
1045
|
+
...engineRuntime.connections
|
|
1046
|
+
.map((e) =>
|
|
1047
|
+
e.storeConnections
|
|
1048
|
+
.map((s) => s.connection.store?.value)
|
|
1049
|
+
.flat(),
|
|
1050
|
+
)
|
|
1051
|
+
.flat(),
|
|
1052
|
+
...engineRuntime.connectionStores
|
|
1053
|
+
.map((e) => e.storePointers.map((sPt) => sPt.value))
|
|
1054
|
+
.flat(),
|
|
1055
|
+
].filter(isNonNullable);
|
|
1056
|
+
assertTrue(Boolean(stores.length), 'No runtime store found');
|
|
1057
|
+
assertTrue(
|
|
1058
|
+
stores.length === 1,
|
|
1059
|
+
'Only one store supported in runtime for function tests',
|
|
1070
1060
|
);
|
|
1061
|
+
const store = guaranteeNonNullable(stores[0]);
|
|
1062
|
+
const data = new FunctionTestData();
|
|
1063
|
+
if (store instanceof Database) {
|
|
1064
|
+
const relation = new RelationElementsData();
|
|
1065
|
+
data.element = PackageableElementExplicitReference.create(store);
|
|
1066
|
+
data.data = relation;
|
|
1067
|
+
} else if (store instanceof ModelStore) {
|
|
1068
|
+
const modelStoreData = createBareExternalFormat();
|
|
1069
|
+
data.element = PackageableElementExplicitReference.create(store);
|
|
1070
|
+
data.data = modelStoreData;
|
|
1071
|
+
} else {
|
|
1072
|
+
throw new UnsupportedOperationError(
|
|
1073
|
+
`function test store data does not support store: ${store.path}`,
|
|
1074
|
+
);
|
|
1075
|
+
}
|
|
1076
|
+
functionSuite.testData = [data];
|
|
1071
1077
|
}
|
|
1072
|
-
functionSuite.testData = [data];
|
|
1073
1078
|
} else {
|
|
1074
1079
|
const type = this.function.returnType.value.rawType;
|
|
1075
1080
|
if (
|
package/src/stores/editor/editor-state/element-editor-state/ingest/IngestDefinitionEditorState.ts
CHANGED
|
@@ -55,6 +55,12 @@ import type { AuthContextProps } from 'react-oidc-context';
|
|
|
55
55
|
import { EXTERNAL_APPLICATION_NAVIGATION__generateUrlWithEditorConfig } from '../../../../../__lib__/LegendStudioNavigation.js';
|
|
56
56
|
import { LineageState } from '@finos/legend-query-builder';
|
|
57
57
|
import { LegendStudioTelemetryHelper } from '../../../../../__lib__/LegendStudioTelemetryHelper.js';
|
|
58
|
+
import { IngestTestableState } from './IngestTestableState.js';
|
|
59
|
+
|
|
60
|
+
export enum INGEST_DEFINITION_TAB {
|
|
61
|
+
DEFINITION = 'Definition',
|
|
62
|
+
TESTING = 'Testing',
|
|
63
|
+
}
|
|
58
64
|
|
|
59
65
|
const createEditorInitialConfiguration = (): EditorInitialConfiguration => {
|
|
60
66
|
const config = new EditorInitialConfiguration();
|
|
@@ -80,11 +86,13 @@ export const generateUrlToDeployOnOpen = (
|
|
|
80
86
|
|
|
81
87
|
const PARSER_SECTION = `###Lakehouse`;
|
|
82
88
|
export class IngestDefinitionEditorState extends ElementEditorState {
|
|
89
|
+
selectedTab = INGEST_DEFINITION_TAB.DEFINITION;
|
|
83
90
|
validateAndDeployResponse: ValidateAndDeploymentResponse | undefined;
|
|
84
91
|
deploymentState = ActionState.create();
|
|
85
92
|
lineageGenerationState = ActionState.create();
|
|
86
93
|
deployOnOpen = false;
|
|
87
94
|
lineageState: LineageState;
|
|
95
|
+
ingestTestableState: IngestTestableState;
|
|
88
96
|
|
|
89
97
|
constructor(
|
|
90
98
|
editorStore: EditorStore,
|
|
@@ -94,11 +102,13 @@ export class IngestDefinitionEditorState extends ElementEditorState {
|
|
|
94
102
|
super(editorStore, element);
|
|
95
103
|
|
|
96
104
|
makeObservable(this, {
|
|
105
|
+
selectedTab: observable,
|
|
97
106
|
deploymentState: observable,
|
|
98
107
|
deployOnOpen: observable,
|
|
99
108
|
setDeployOnOpen: observable,
|
|
100
109
|
validateAndDeployResponse: observable,
|
|
101
110
|
deploymentResponse: computed,
|
|
111
|
+
setSelectedTab: action,
|
|
102
112
|
setValidateAndDeployResponse: action,
|
|
103
113
|
init_with_deploy: flow,
|
|
104
114
|
deploy: flow,
|
|
@@ -112,6 +122,12 @@ export class IngestDefinitionEditorState extends ElementEditorState {
|
|
|
112
122
|
config.elementEditorConfiguration.deployOnOpen ?? false;
|
|
113
123
|
}
|
|
114
124
|
this.lineageState = new LineageState(this.editorStore.applicationStore);
|
|
125
|
+
this.ingestTestableState = new IngestTestableState(this);
|
|
126
|
+
this.ingestTestableState.init();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
setSelectedTab(val: INGEST_DEFINITION_TAB): void {
|
|
130
|
+
this.selectedTab = val;
|
|
115
131
|
}
|
|
116
132
|
|
|
117
133
|
get deploymentResponse():
|