From f764cedbacbf9d11740760f0a6492c6d0dd0587a Mon Sep 17 00:00:00 2001 From: Mauricio Uyaguari Date: Sun, 9 Jul 2023 20:38:49 -0400 Subject: [PATCH] improve support for extensions in tests (#2414) --- .changeset/tricky-donkeys-fly.md | 4 ++ .../mapping-editor/MappingTestableEditor.tsx | 4 +- .../mapping/testable/MappingTestableState.ts | 2 +- .../mapping/testable/MappingTestingHelper.ts | 15 ++++++ .../src/stores/editor/utils/TestableUtils.ts | 41 ++++++++++++++-- ...LegendStudioApplicationPlugin_Extension.ts | 34 ++++++++++++- ...iceStore_LegendStudioApplicationPlugin.tsx | 48 +++++++++++++++++++ 7 files changed, 142 insertions(+), 6 deletions(-) create mode 100644 .changeset/tricky-donkeys-fly.md diff --git a/.changeset/tricky-donkeys-fly.md b/.changeset/tricky-donkeys-fly.md new file mode 100644 index 0000000000..316a2090ab --- /dev/null +++ b/.changeset/tricky-donkeys-fly.md @@ -0,0 +1,4 @@ +--- +'@finos/legend-extension-store-service-store': patch +'@finos/legend-application-studio': patch +--- diff --git a/packages/legend-application-studio/src/components/editor/editor-group/mapping-editor/MappingTestableEditor.tsx b/packages/legend-application-studio/src/components/editor/editor-group/mapping-editor/MappingTestableEditor.tsx index 3cd2c39554..51708f2e5a 100644 --- a/packages/legend-application-studio/src/components/editor/editor-group/mapping-editor/MappingTestableEditor.tsx +++ b/packages/legend-application-studio/src/components/editor/editor-group/mapping-editor/MappingTestableEditor.tsx @@ -734,7 +734,9 @@ const StoreTestDataEditor = observer( if (isUsingReference) { const newBare = returnUndefOnError(() => currentData.accept_EmbeddedDataVisitor( - new EmbeddedDataCreatorFromEmbeddedData(), + new EmbeddedDataCreatorFromEmbeddedData( + mappingTestState.editorStore, + ), ), ); if (newBare) { diff --git a/packages/legend-application-studio/src/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.ts b/packages/legend-application-studio/src/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.ts index 63fcd4fabd..bbb09bb836 100644 --- a/packages/legend-application-studio/src/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.ts +++ b/packages/legend-application-studio/src/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestableState.ts @@ -409,7 +409,7 @@ export class MappingTestSuiteState extends TestableTestSuiteEditorState { firstData.store.value, ); storeTestData.data = firstData.data.accept_EmbeddedDataVisitor( - new EmbeddedDataCreatorFromEmbeddedData(), + new EmbeddedDataCreatorFromEmbeddedData(this.editorStore), ); return storeTestData; } else if (targetClass) { diff --git a/packages/legend-application-studio/src/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestingHelper.ts b/packages/legend-application-studio/src/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestingHelper.ts index e1aeaff8af..6eb15e005f 100644 --- a/packages/legend-application-studio/src/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestingHelper.ts +++ b/packages/legend-application-studio/src/stores/editor/editor-state/element-editor-state/mapping/testable/MappingTestingHelper.ts @@ -62,6 +62,7 @@ import { assertTrue, guaranteeNonNullable, } from '@finos/legend-shared'; +import type { DSL_Data_LegendStudioApplicationPlugin_Extension } from '../../../../../extensions/DSL_Data_LegendStudioApplicationPlugin_Extension.js'; export const createGraphFetchRawLambda = ( mainClass: Class, @@ -137,6 +138,20 @@ export const generateStoreTestDataFromSetImpl = ( return createStoreBareModelStoreData(srcClass.value, editorStore); } } + const extraStoreDataCreators = editorStore.pluginManager + .getApplicationPlugins() + .flatMap( + (plugin) => + ( + plugin as DSL_Data_LegendStudioApplicationPlugin_Extension + ).getExtraStoreTestDataCreators?.() ?? [], + ); + for (const creator of extraStoreDataCreators) { + const embeddedData = creator(setImpl); + if (embeddedData) { + return embeddedData; + } + } return undefined; }; diff --git a/packages/legend-application-studio/src/stores/editor/utils/TestableUtils.ts b/packages/legend-application-studio/src/stores/editor/utils/TestableUtils.ts index 53f43e026f..140247473c 100644 --- a/packages/legend-application-studio/src/stores/editor/utils/TestableUtils.ts +++ b/packages/legend-application-studio/src/stores/editor/utils/TestableUtils.ts @@ -59,6 +59,7 @@ import { import { EmbeddedDataType } from '../editor-state/ExternalFormatState.js'; import type { EditorStore } from '../EditorStore.js'; import { createMockDataForMappingElementSource } from './MockDataUtils.js'; +import type { DSL_Data_LegendStudioApplicationPlugin_Extension } from '../../extensions/DSL_Data_LegendStudioApplicationPlugin_Extension.js'; export const DEFAULT_TEST_ASSERTION_ID = 'assertion_1'; export const DEFAULT_TEST_ID = 'test_1'; @@ -127,8 +128,28 @@ export const createBareModelStoreData = ( export class EmbeddedDataCreatorFromEmbeddedData implements EmbeddedDataVisitor { + editorStore: EditorStore; + constructor(editorStore: EditorStore) { + this.editorStore = editorStore; + } visit_EmbeddedData(data: EmbeddedData): EmbeddedData { - throw new Error('Method not implemented.'); + const extraEmbeddedDataCloners = this.editorStore.pluginManager + .getApplicationPlugins() + .flatMap( + (plugin) => + ( + plugin as DSL_Data_LegendStudioApplicationPlugin_Extension + ).getExtraEmbeddedDataCloners?.() ?? [], + ); + for (const creator of extraEmbeddedDataCloners) { + const embeddedData = creator(data); + if (embeddedData) { + return embeddedData; + } + } + throw new UnsupportedOperationError( + `Unsupported embedded data${data.toString()}`, + ); } visit_INTERNAL__UnknownEmbeddedData( data: INTERNAL__UnknownEmbeddedData, @@ -149,7 +170,7 @@ export class EmbeddedDataCreatorFromEmbeddedData const v = new ModelEmbeddedData(); v.model = PackageableElementExplicitReference.create(e.model.value); v.data = e.data.accept_EmbeddedDataVisitor( - new EmbeddedDataCreatorFromEmbeddedData(), + new EmbeddedDataCreatorFromEmbeddedData(this.editorStore), ); return v; } @@ -160,7 +181,7 @@ export class EmbeddedDataCreatorFromEmbeddedData } visit_DataElementReference(data: DataElementReference): EmbeddedData { return data.dataElement.value.data.accept_EmbeddedDataVisitor( - new EmbeddedDataCreatorFromEmbeddedData(), + new EmbeddedDataCreatorFromEmbeddedData(this.editorStore), ); } visit_RelationalCSVData(data: RelationalCSVData): EmbeddedData { @@ -224,6 +245,20 @@ export class EmbeddedDataConnectionTypeVisitor } visit_Connection(connection: Connection): string { + const extraEmbeddedDataCreator = this.editorStore.pluginManager + .getApplicationPlugins() + .flatMap( + (plugin) => + ( + plugin as DSL_Data_LegendStudioApplicationPlugin_Extension + ).getExtraEmbeddedDataTypeFromConnectionMatchers?.() ?? [], + ); + for (const creator of extraEmbeddedDataCreator) { + const embeddedData = creator(connection); + if (embeddedData) { + return embeddedData; + } + } return EmbeddedDataType.EXTERNAL_FORMAT_DATA; } visit_INTERNAL__UnknownConnection( diff --git a/packages/legend-application-studio/src/stores/extensions/DSL_Data_LegendStudioApplicationPlugin_Extension.ts b/packages/legend-application-studio/src/stores/extensions/DSL_Data_LegendStudioApplicationPlugin_Extension.ts index b1045b2dda..46e380c5d0 100644 --- a/packages/legend-application-studio/src/stores/extensions/DSL_Data_LegendStudioApplicationPlugin_Extension.ts +++ b/packages/legend-application-studio/src/stores/extensions/DSL_Data_LegendStudioApplicationPlugin_Extension.ts @@ -14,7 +14,12 @@ * limitations under the License. */ -import type { EmbeddedData } from '@finos/legend-graph'; +import type { + Connection, + EmbeddedData, + SetImplementation, + StoreTestData, +} from '@finos/legend-graph'; import type { EmbeddedDataTypeOption } from '../editor/editor-state/element-editor-state/data/DataEditorState.js'; import type { EmbeddedDataState } from '../editor/editor-state/element-editor-state/data/EmbeddedDataState.js'; import type { EditorStore } from '../editor/EditorStore.js'; @@ -35,6 +40,18 @@ export type EmbeddedDataCreator = ( embeddedDataType: string, ) => EmbeddedData | undefined; +export type EmbeddedDataCloner = ( + embeddedData: EmbeddedData, +) => EmbeddedData | undefined; + +export type StoreTestDataCreators = ( + setImp: SetImplementation, +) => StoreTestData | undefined; + +export type EmbeddedDataTypeFromConnectionMatcher = ( + connection: Connection, +) => string | undefined; + /** * NOTE: The tab-stop index of the snippet must start from 2 */ @@ -67,4 +84,19 @@ export interface DSL_Data_LegendStudioApplicationPlugin_Extension * Get the list of embedded data creators */ getExtraEmbeddedDataCreators?(): EmbeddedDataCreator[]; + + /** + * Get the list of embedded data type from connection matchers + */ + getExtraEmbeddedDataTypeFromConnectionMatchers?(): EmbeddedDataTypeFromConnectionMatcher[]; + + /** + * Get the list of store test data creators + */ + getExtraStoreTestDataCreators?(): StoreTestDataCreators[]; + + /** + * Get the list of embedded data cloners + */ + getExtraEmbeddedDataCloners?(): EmbeddedDataCloner[]; } diff --git a/packages/legend-extension-store-service-store/src/components/studio/STO_ServiceStore_LegendStudioApplicationPlugin.tsx b/packages/legend-extension-store-service-store/src/components/studio/STO_ServiceStore_LegendStudioApplicationPlugin.tsx index 268950aa6e..4743a980cd 100644 --- a/packages/legend-extension-store-service-store/src/components/studio/STO_ServiceStore_LegendStudioApplicationPlugin.tsx +++ b/packages/legend-extension-store-service-store/src/components/studio/STO_ServiceStore_LegendStudioApplicationPlugin.tsx @@ -54,6 +54,9 @@ import { type MappingElementSource, type ConnectionTypeOption, type PureGrammarConnectionLabeler, + type EmbeddedDataTypeFromConnectionMatcher, + type StoreTestDataCreators, + type EmbeddedDataCloner, } from '@finos/legend-application-studio'; import { SwaggerIcon } from '@finos/legend-art'; import { @@ -61,7 +64,9 @@ import { type EmbeddedData, type PackageableElement, type Store, + type SetImplementation, PackageableElementExplicitReference, + StoreTestData, } from '@finos/legend-graph'; import { ServiceStore } from '../../graph/metamodel/pure/model/packageableElements/store/serviceStore/model/STO_ServiceStore_ServiceStore.js'; import { RootServiceInstanceSetImplementation } from '../../graph/metamodel/pure/model/packageableElements/store/serviceStore/mapping/STO_ServiceStore_RootServiceInstanceSetImplementation.js'; @@ -488,4 +493,47 @@ export class STO_ServiceStore_LegendStudioApplicationPlugin }, ]; } + + getExtraEmbeddedDataCloners(): EmbeddedDataCloner[] { + return [ + (embeddedData: EmbeddedData): EmbeddedData | undefined => { + if (embeddedData instanceof ServiceStoreEmbeddedData) { + const serviceStoreEmbeddedData = new ServiceStoreEmbeddedData(); + // TODO walk embedded data and clone + return serviceStoreEmbeddedData; + } + return undefined; + }, + ]; + } + + getExtraEmbeddedDataTypeFromConnectionMatchers(): EmbeddedDataTypeFromConnectionMatcher[] { + return [ + (connection: Connection): string | undefined => { + if (connection instanceof ServiceStoreConnection) { + return SERVICE_STORE_EMBEDDED_DATA_TYPE; + } + return undefined; + }, + ]; + } + + getExtraStoreTestDataCreators(): StoreTestDataCreators[] { + return [ + (setImpl: SetImplementation): StoreTestData | undefined => { + if (setImpl instanceof RootServiceInstanceSetImplementation) { + const storeTestData = new StoreTestData(); + storeTestData.data = new ServiceStoreEmbeddedData(); + const serviceMapping = setImpl.servicesMapping[0]; + if (serviceMapping) { + storeTestData.store = PackageableElementExplicitReference.create( + serviceMapping.service.owner, + ); + } + return storeTestData; + } + return undefined; + }, + ]; + } }