From ce2cccfa2a42dd63427cf654cd2215f254a099aa Mon Sep 17 00:00:00 2001 From: Tim Chamberlain Date: Wed, 30 Nov 2022 11:29:48 -0600 Subject: [PATCH] SPRINT-16: added more tests --- .../actions/dashboard/RenderWidgetAction.java | 2 +- .../widgets/ParentWidgetRenderer.java | 8 +- .../dashboard/widgets/ProcessWidgetData.java | 41 +++- .../possiblevalues/QPossibleValueSource.java | 35 ++++ .../widgets/ParentWidgetRendererTest.java | 180 ++++++++++++++++++ .../widgets/ProcessWidgetRendererTest.java | 166 ++++++++++++++++ .../qqq/backend/core/utils/TestUtils.java | 4 +- 7 files changed, 427 insertions(+), 9 deletions(-) create mode 100644 qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ParentWidgetRendererTest.java create mode 100644 qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ProcessWidgetRendererTest.java diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/RenderWidgetAction.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/RenderWidgetAction.java index a98416a0..225d3f19 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/RenderWidgetAction.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/RenderWidgetAction.java @@ -57,7 +57,7 @@ public class RenderWidgetAction { for(Map.Entry entry : widgetMetaData.getDefaultValues().entrySet()) { - input.getQueryParams().putIfAbsent(entry.getKey(), ValueUtils.getValueAsString(entry.getValue())); + input.addQueryParam(entry.getKey(), ValueUtils.getValueAsString(entry.getValue())); } } diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ParentWidgetRenderer.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ParentWidgetRenderer.java index 65e1805f..db27b707 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ParentWidgetRenderer.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ParentWidgetRenderer.java @@ -38,7 +38,7 @@ import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetOutput; import com.kingsrook.qqq.backend.core.model.dashboard.widgets.ParentWidgetData; import com.kingsrook.qqq.backend.core.model.metadata.dashboard.ParentWidgetMetaData; import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValue; -import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource; import com.kingsrook.qqq.backend.core.utils.CollectionUtils; @@ -70,9 +70,9 @@ public class ParentWidgetRenderer extends AbstractWidgetRenderer List pvsNames = new ArrayList<>(); for(String possibleValueSourceName : CollectionUtils.nonNullList(metaData.getPossibleValueNameList())) { - QTableMetaData tableMetaData = input.getInstance().getTable(input.getInstance().getPossibleValueSource(possibleValueSourceName).getTableName()); - pvsLabels.add(tableMetaData.getLabel()); - pvsNames.add(tableMetaData.getName()); + QPossibleValueSource possibleValueSource = input.getInstance().getPossibleValueSource(possibleValueSourceName); + pvsLabels.add(possibleValueSource.getLabel() != null ? possibleValueSource.getLabel() : possibleValueSourceName); + pvsNames.add(possibleValueSourceName); SearchPossibleValueSourceInput pvsInput = new SearchPossibleValueSourceInput(input.getInstance()); pvsInput.setSession(input.getSession()); diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/ProcessWidgetData.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/ProcessWidgetData.java index bac2ef26..a941fbdb 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/ProcessWidgetData.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/dashboard/widgets/ProcessWidgetData.java @@ -22,16 +22,19 @@ package com.kingsrook.qqq.backend.core.model.dashboard.widgets; +import java.io.Serializable; +import java.util.Map; import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData; /******************************************************************************* - ** Model containing datastructure expected by frontend stepper widget + ** Model containing datastructure expected by frontend process widget ** *******************************************************************************/ public class ProcessWidgetData implements QWidget { - private QProcessMetaData processMetaData; + private QProcessMetaData processMetaData; + private Map defaultValues; @@ -78,4 +81,38 @@ public class ProcessWidgetData implements QWidget return (this); } + + + /******************************************************************************* + ** Getter for defaultValues + ** + *******************************************************************************/ + public Map getDefaultValues() + { + return defaultValues; + } + + + + /******************************************************************************* + ** Setter for defaultValues + ** + *******************************************************************************/ + public void setDefaultValues(Map defaultValues) + { + this.defaultValues = defaultValues; + } + + + + /******************************************************************************* + ** Fluent setter for defaultValues + ** + *******************************************************************************/ + public ProcessWidgetData withDefaultValues(Map defaultValues) + { + this.defaultValues = defaultValues; + return (this); + } + } diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/possiblevalues/QPossibleValueSource.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/possiblevalues/QPossibleValueSource.java index 280c3c4e..c4fe0551 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/possiblevalues/QPossibleValueSource.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/possiblevalues/QPossibleValueSource.java @@ -37,6 +37,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference; public class QPossibleValueSource { private String name; + private String label; private QPossibleValueSourceType type; private String valueFormat = PVSValueFormatAndFields.LABEL_ONLY.getFormat(); @@ -105,6 +106,40 @@ public class QPossibleValueSource + /******************************************************************************* + ** Getter for label + ** + *******************************************************************************/ + public String getLabel() + { + return label; + } + + + + /******************************************************************************* + ** Setter for label + ** + *******************************************************************************/ + public void setLabel(String label) + { + this.label = label; + } + + + + /******************************************************************************* + ** Fluent setter for label + ** + *******************************************************************************/ + public QPossibleValueSource withLabel(String label) + { + this.label = label; + return (this); + } + + + /******************************************************************************* ** *******************************************************************************/ diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ParentWidgetRendererTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ParentWidgetRendererTest.java new file mode 100644 index 00000000..3c927c8d --- /dev/null +++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ParentWidgetRendererTest.java @@ -0,0 +1,180 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2022. Kingsrook, LLC + * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States + * contact@kingsrook.com + * https://github.com/Kingsrook/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.kingsrook.qqq.backend.core.actions.dashboard.widgets; + + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import com.kingsrook.qqq.backend.core.actions.dashboard.RenderWidgetAction; +import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput; +import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetOutput; +import com.kingsrook.qqq.backend.core.model.dashboard.widgets.ChildRecordListData; +import com.kingsrook.qqq.backend.core.model.dashboard.widgets.ParentWidgetData; +import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType; +import com.kingsrook.qqq.backend.core.model.data.QRecord; +import com.kingsrook.qqq.backend.core.model.metadata.QInstance; +import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference; +import com.kingsrook.qqq.backend.core.model.metadata.dashboard.ParentWidgetMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaDataInterface; +import com.kingsrook.qqq.backend.core.model.session.QSession; +import com.kingsrook.qqq.backend.core.modules.backend.implementations.memory.MemoryRecordStore; +import com.kingsrook.qqq.backend.core.utils.TestUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; + + +/******************************************************************************* + ** Unit test for ChildRecordListRenderer + *******************************************************************************/ +class ParentWidgetRendererTest +{ + + /******************************************************************************* + ** + *******************************************************************************/ + @BeforeEach + @AfterEach + void beforeAndAfterEach() + { + MemoryRecordStore.getInstance().reset(); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testParentWidget() throws QException + { + QInstance qInstance = TestUtils.defineInstance(); + + QWidgetMetaDataInterface parcelRulesWidget = new ParentWidgetMetaData() + .withTitle("Parcel Rules") + .withPossibleValueNameList( + List.of( + TestUtils.defineStatesPossibleValueSource().getName(), + TestUtils.defineShapePossibleValueSource().getName() + ) + ) + .withChildWidgetNameList( + List.of( + ProcessWidgetRenderer.class.getSimpleName() + ) + ) + .withType(WidgetType.PARENT_WIDGET.getType()) + .withName(ProcessWidgetRenderer.class.getSimpleName()) + .withGridColumns(12) + .withLabel("Test Parent Widget") + .withCodeReference(new QCodeReference(ParentWidgetRenderer.class, null)) + .withIcon("local_shipping"); + qInstance.addWidget(parcelRulesWidget); + + RenderWidgetInput input = new RenderWidgetInput(qInstance); + input.setSession(new QSession()); + input.setWidgetMetaData(parcelRulesWidget); + + RenderWidgetAction renderWidgetAction = new RenderWidgetAction(); + RenderWidgetOutput output = renderWidgetAction.execute(input); + + assertThat(output.getWidgetData()).isNotNull(); + ParentWidgetData parentWidgetData = (ParentWidgetData) output.getWidgetData(); + assertThat(parentWidgetData.getDropdownDataList().size()).isEqualTo(2); + assertThat(parentWidgetData.getChildWidgetNameList().size()).isEqualTo(1); + assertThat(parentWidgetData.getType()).isEqualTo(WidgetType.PARENT_WIDGET.getType()); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testNoChildRecordsFound() throws QException + { + QInstance qInstance = TestUtils.defineInstance(); + QWidgetMetaData widget = ChildRecordListRenderer.defineWidgetFromJoin(qInstance.getJoin("orderLineItem")) + .withLabel("Line Items"); + qInstance.addWidget(widget); + + TestUtils.insertRecords(qInstance, qInstance.getTable(TestUtils.TABLE_NAME_ORDER), List.of( + new QRecord().withValue("id", 1) + )); + + RenderWidgetInput input = new RenderWidgetInput(qInstance); + input.setSession(new QSession()); + input.setWidgetMetaData(widget); + input.setQueryParams(new HashMap<>(Map.of("id", "1"))); + + RenderWidgetAction renderWidgetAction = new RenderWidgetAction(); + RenderWidgetOutput output = renderWidgetAction.execute(input); + + ChildRecordListData childRecordListData = (ChildRecordListData) output.getWidgetData(); + assertThat(childRecordListData.getChildTableMetaData()).hasFieldOrPropertyWithValue("name", TestUtils.TABLE_NAME_LINE_ITEM); + assertThat(childRecordListData.getQueryOutput().getRecords()).isEmpty(); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testChildRecordsFound() throws QException + { + QInstance qInstance = TestUtils.defineInstance(); + QWidgetMetaData widget = ChildRecordListRenderer.defineWidgetFromJoin(qInstance.getJoin("orderLineItem")) + .withLabel("Line Items"); + qInstance.addWidget(widget); + + TestUtils.insertRecords(qInstance, qInstance.getTable(TestUtils.TABLE_NAME_ORDER), List.of( + new QRecord().withValue("id", 1), + new QRecord().withValue("id", 2) + )); + + TestUtils.insertRecords(qInstance, qInstance.getTable(TestUtils.TABLE_NAME_LINE_ITEM), List.of( + new QRecord().withValue("orderId", 1).withValue("sku", "ABC").withValue("lineNumber", 2), + new QRecord().withValue("orderId", 1).withValue("sku", "BCD").withValue("lineNumber", 1), + new QRecord().withValue("orderId", 2).withValue("sku", "XYZ") // should not be found. + )); + + RenderWidgetInput input = new RenderWidgetInput(qInstance); + input.setSession(new QSession()); + input.setWidgetMetaData(widget); + input.setQueryParams(new HashMap<>(Map.of("id", "1"))); + + RenderWidgetAction renderWidgetAction = new RenderWidgetAction(); + RenderWidgetOutput output = renderWidgetAction.execute(input); + + ChildRecordListData childRecordListData = (ChildRecordListData) output.getWidgetData(); + assertThat(childRecordListData.getChildTableMetaData()).hasFieldOrPropertyWithValue("name", TestUtils.TABLE_NAME_LINE_ITEM); + assertThat(childRecordListData.getQueryOutput().getRecords()).hasSize(2); + assertThat(childRecordListData.getQueryOutput().getRecords().get(0).getValueString("sku")).isEqualTo("BCD"); + assertThat(childRecordListData.getQueryOutput().getRecords().get(1).getValueString("sku")).isEqualTo("ABC"); + } + +} diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ProcessWidgetRendererTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ProcessWidgetRendererTest.java new file mode 100644 index 00000000..97fbbdd8 --- /dev/null +++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/ProcessWidgetRendererTest.java @@ -0,0 +1,166 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2022. Kingsrook, LLC + * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States + * contact@kingsrook.com + * https://github.com/Kingsrook/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.kingsrook.qqq.backend.core.actions.dashboard.widgets; + + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import com.kingsrook.qqq.backend.core.actions.dashboard.RenderWidgetAction; +import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput; +import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetOutput; +import com.kingsrook.qqq.backend.core.model.dashboard.widgets.ChildRecordListData; +import com.kingsrook.qqq.backend.core.model.dashboard.widgets.ProcessWidgetData; +import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType; +import com.kingsrook.qqq.backend.core.model.data.QRecord; +import com.kingsrook.qqq.backend.core.model.metadata.QInstance; +import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference; +import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData; +import com.kingsrook.qqq.backend.core.model.session.QSession; +import com.kingsrook.qqq.backend.core.modules.backend.implementations.memory.MemoryRecordStore; +import com.kingsrook.qqq.backend.core.utils.TestUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; + + +/******************************************************************************* + ** Unit test for ChildRecordListRenderer + *******************************************************************************/ +class ProcessWidgetRendererTest +{ + + /******************************************************************************* + ** + *******************************************************************************/ + @BeforeEach + @AfterEach + void beforeAndAfterEach() + { + MemoryRecordStore.getInstance().reset(); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testProcessWidger() throws QException + { + QInstance qInstance = TestUtils.defineInstance(); + + QWidgetMetaData metaData = new QWidgetMetaData() + .withType(WidgetType.PROCESS.getType()) + .withName(ProcessWidgetRenderer.class.getSimpleName()) + .withDefaultValue(ProcessWidgetRenderer.WIDGET_PROCESS_NAME, TestUtils.PROCESS_NAME_GREET_PEOPLE) + .withLabel("Test Process Widget") + .withGridColumns(6) + .withCodeReference(new QCodeReference(ProcessWidgetRenderer.class, null)); + qInstance.addWidget(metaData); + + RenderWidgetInput input = new RenderWidgetInput(qInstance); + input.setSession(new QSession()); + input.setWidgetMetaData(metaData); + + RenderWidgetAction renderWidgetAction = new RenderWidgetAction(); + RenderWidgetOutput output = renderWidgetAction.execute(input); + + assertThat(output.getWidgetData()).isNotNull(); + ProcessWidgetData processWidgetData = (ProcessWidgetData) output.getWidgetData(); + assertThat(processWidgetData.getProcessMetaData()).isNotNull(); + assertThat(processWidgetData.getProcessMetaData().getName()).isEqualTo(TestUtils.PROCESS_NAME_GREET_PEOPLE); + assertThat(processWidgetData.getType()).isEqualTo(WidgetType.PROCESS.getType()); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testNoChildRecordsFound() throws QException + { + QInstance qInstance = TestUtils.defineInstance(); + QWidgetMetaData widget = ChildRecordListRenderer.defineWidgetFromJoin(qInstance.getJoin("orderLineItem")) + .withLabel("Line Items"); + qInstance.addWidget(widget); + + TestUtils.insertRecords(qInstance, qInstance.getTable(TestUtils.TABLE_NAME_ORDER), List.of( + new QRecord().withValue("id", 1) + )); + + RenderWidgetInput input = new RenderWidgetInput(qInstance); + input.setSession(new QSession()); + input.setWidgetMetaData(widget); + input.setQueryParams(new HashMap<>(Map.of("id", "1"))); + + RenderWidgetAction renderWidgetAction = new RenderWidgetAction(); + RenderWidgetOutput output = renderWidgetAction.execute(input); + + ChildRecordListData childRecordListData = (ChildRecordListData) output.getWidgetData(); + assertThat(childRecordListData.getChildTableMetaData()).hasFieldOrPropertyWithValue("name", TestUtils.TABLE_NAME_LINE_ITEM); + assertThat(childRecordListData.getQueryOutput().getRecords()).isEmpty(); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testChildRecordsFound() throws QException + { + QInstance qInstance = TestUtils.defineInstance(); + QWidgetMetaData widget = ChildRecordListRenderer.defineWidgetFromJoin(qInstance.getJoin("orderLineItem")) + .withLabel("Line Items"); + qInstance.addWidget(widget); + + TestUtils.insertRecords(qInstance, qInstance.getTable(TestUtils.TABLE_NAME_ORDER), List.of( + new QRecord().withValue("id", 1), + new QRecord().withValue("id", 2) + )); + + TestUtils.insertRecords(qInstance, qInstance.getTable(TestUtils.TABLE_NAME_LINE_ITEM), List.of( + new QRecord().withValue("orderId", 1).withValue("sku", "ABC").withValue("lineNumber", 2), + new QRecord().withValue("orderId", 1).withValue("sku", "BCD").withValue("lineNumber", 1), + new QRecord().withValue("orderId", 2).withValue("sku", "XYZ") // should not be found. + )); + + RenderWidgetInput input = new RenderWidgetInput(qInstance); + input.setSession(new QSession()); + input.setWidgetMetaData(widget); + input.setQueryParams(new HashMap<>(Map.of("id", "1"))); + + RenderWidgetAction renderWidgetAction = new RenderWidgetAction(); + RenderWidgetOutput output = renderWidgetAction.execute(input); + + ChildRecordListData childRecordListData = (ChildRecordListData) output.getWidgetData(); + assertThat(childRecordListData.getChildTableMetaData()).hasFieldOrPropertyWithValue("name", TestUtils.TABLE_NAME_LINE_ITEM); + assertThat(childRecordListData.getQueryOutput().getRecords()).hasSize(2); + assertThat(childRecordListData.getQueryOutput().getRecords().get(0).getValueString("sku")).isEqualTo("BCD"); + assertThat(childRecordListData.getQueryOutput().getRecords().get(1).getValueString("sku")).isEqualTo("ABC"); + } + +} diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/utils/TestUtils.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/utils/TestUtils.java index fb0ed5d2..749896ac 100644 --- a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/utils/TestUtils.java +++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/utils/TestUtils.java @@ -349,7 +349,7 @@ public class TestUtils ** Define the "states" possible value source used in standard tests ** *******************************************************************************/ - private static QPossibleValueSource defineStatesPossibleValueSource() + public static QPossibleValueSource defineStatesPossibleValueSource() { return new QPossibleValueSource() .withName(POSSIBLE_VALUE_SOURCE_STATE) @@ -363,7 +363,7 @@ public class TestUtils ** Define the "shape" possible value source used in standard tests ** *******************************************************************************/ - private static QPossibleValueSource defineShapePossibleValueSource() + public static QPossibleValueSource defineShapePossibleValueSource() { return new QPossibleValueSource() .withName(POSSIBLE_VALUE_SOURCE_SHAPE)