diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/scripts/TestScriptAction.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/scripts/TestScriptAction.java
deleted file mode 100644
index 7e9e1e5d..00000000
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/scripts/TestScriptAction.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.scripts;
-
-
-import java.util.HashMap;
-import com.kingsrook.qqq.backend.core.actions.scripts.logging.BuildScriptLogAndScriptLogLineExecutionLogger;
-import com.kingsrook.qqq.backend.core.exceptions.QException;
-import com.kingsrook.qqq.backend.core.model.actions.scripts.ExecuteCodeInput;
-import com.kingsrook.qqq.backend.core.model.actions.scripts.ExecuteCodeOutput;
-import com.kingsrook.qqq.backend.core.model.actions.scripts.TestScriptInput;
-import com.kingsrook.qqq.backend.core.model.actions.scripts.TestScriptOutput;
-import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
-import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeType;
-import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
-
-
-/*******************************************************************************
- ** Class for running a test of a script - e.g., maybe before it is saved.
- *******************************************************************************/
-public class TestScriptAction
-{
-
- /*******************************************************************************
- **
- *******************************************************************************/
- public void run(TestScriptInput input, TestScriptOutput output) throws QException
- {
- QTableMetaData table = input.getTable();
-
- ExecuteCodeInput executeCodeInput = new ExecuteCodeInput(input.getInstance());
- executeCodeInput.setSession(input.getSession());
- executeCodeInput.setInput(new HashMap<>(input.getInputValues()));
- executeCodeInput.setContext(new HashMap<>());
- // todo! if(input.getOutputObject() != null)
- // todo! {
- // todo! executeCodeInput.getContext().put("output", input.getOutputObject());
- // todo! }
- executeCodeInput.setCodeReference(new QCodeReference().withInlineCode(input.getCode()).withCodeType(QCodeType.JAVA_SCRIPT)); // todo - code type as attribute of script!!
- executeCodeInput.setExecutionLogger(new BuildScriptLogAndScriptLogLineExecutionLogger());
- ExecuteCodeOutput executeCodeOutput = new ExecuteCodeOutput();
- new ExecuteCodeAction().run(executeCodeInput, executeCodeOutput);
-
- // todo! output.setOutput(executeCodeOutput.getOutput());
- }
-}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/scripts/TestScriptActionInterface.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/scripts/TestScriptActionInterface.java
new file mode 100644
index 00000000..d2cf509f
--- /dev/null
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/scripts/TestScriptActionInterface.java
@@ -0,0 +1,109 @@
+/*
+ * 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.scripts;
+
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import com.kingsrook.qqq.backend.core.actions.scripts.logging.BuildScriptLogAndScriptLogLineExecutionLogger;
+import com.kingsrook.qqq.backend.core.exceptions.QException;
+import com.kingsrook.qqq.backend.core.model.actions.scripts.ExecuteCodeInput;
+import com.kingsrook.qqq.backend.core.model.actions.scripts.ExecuteCodeOutput;
+import com.kingsrook.qqq.backend.core.model.actions.scripts.TestScriptInput;
+import com.kingsrook.qqq.backend.core.model.actions.scripts.TestScriptOutput;
+import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
+
+
+/*******************************************************************************
+ ** Interface to be implemented by script-running actions, if they want to allow
+ ** themselves to be used for user-testing of their script.
+ *******************************************************************************/
+public interface TestScriptActionInterface
+{
+ /*******************************************************************************
+ ** Called to adapt or translate data from the TestScriptInput (which would just
+ ** have a map of name-value pairs) to the actual input object(s) used by the script.
+ **
+ ** Note - such a method may want or need to put an "output" object into the
+ ** executeCodeInput's context map.
+ *******************************************************************************/
+ void setupTestScriptInput(TestScriptInput testScriptInput, ExecuteCodeInput executeCodeInput);
+
+
+ /*******************************************************************************
+ ** Called to adapt or translate the output object of the script execution to
+ ** something suitable for returning to the caller.
+ **
+ ** Default implementation may always be suitable?
+ *******************************************************************************/
+ default Serializable processTestScriptOutput(ExecuteCodeOutput executeCodeOutput)
+ {
+ return (executeCodeOutput.getOutput());
+ }
+
+
+ /*******************************************************************************
+ ** Define the list of input fields for testing the script. The names of these
+ ** fields will end up as keys in the setupTestScriptInput method's testScriptInput object.
+ *******************************************************************************/
+ List getTestInputFields();
+
+
+ /*******************************************************************************
+ ** Define the list of output fields when testing the script. The output object
+ ** returned from processTestScriptOutput should have keys that match these field names.
+ *******************************************************************************/
+ List getTestOutputFields();
+
+ /*******************************************************************************
+ ** Execute a test script.
+ *******************************************************************************/
+ default void execute(TestScriptInput input, TestScriptOutput output) throws QException
+ {
+ ExecuteCodeInput executeCodeInput = new ExecuteCodeInput(input.getInstance());
+ executeCodeInput.setSession(input.getSession());
+ executeCodeInput.setContext(new HashMap<>());
+
+ executeCodeInput.setCodeReference(input.getCodeReference());
+ BuildScriptLogAndScriptLogLineExecutionLogger executionLogger = new BuildScriptLogAndScriptLogLineExecutionLogger(null, null);
+ executeCodeInput.setExecutionLogger(executionLogger);
+
+ setupTestScriptInput(input, executeCodeInput);
+
+ ExecuteCodeOutput executeCodeOutput = new ExecuteCodeOutput();
+
+ try
+ {
+ new ExecuteCodeAction().run(executeCodeInput, executeCodeOutput);
+ output.setOutputObject(processTestScriptOutput(executeCodeOutput));
+ }
+ catch(Exception e)
+ {
+ output.setException(e);
+ }
+
+ output.setScriptLog(executionLogger.getScriptLog());
+ output.setScriptLogLines(executionLogger.getScriptLogLines());
+ }
+
+}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/QInstanceEnricher.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/QInstanceEnricher.java
index 078c7843..98631e8b 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/QInstanceEnricher.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/QInstanceEnricher.java
@@ -230,7 +230,7 @@ public class QInstanceEnricher
/*******************************************************************************
**
*******************************************************************************/
- private void enrichField(QFieldMetaData field)
+ public void enrichField(QFieldMetaData field)
{
if(!StringUtils.hasContent(field.getLabel()))
{
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/actions/scripts/TestScriptInput.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/actions/scripts/TestScriptInput.java
index 33871f38..4021e27b 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/actions/scripts/TestScriptInput.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/actions/scripts/TestScriptInput.java
@@ -26,6 +26,7 @@ import java.io.Serializable;
import java.util.Map;
import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput;
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
+import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
/*******************************************************************************
@@ -33,10 +34,8 @@ import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
*******************************************************************************/
public class TestScriptInput extends AbstractTableActionInput
{
- private Serializable recordPrimaryKey;
- private String code;
- private Serializable scriptTypeId;
- private Map inputValues;
+ private Map inputValues;
+ private QCodeReference codeReference;
@@ -50,45 +49,11 @@ public class TestScriptInput extends AbstractTableActionInput
- /*******************************************************************************
- ** Getter for recordPrimaryKey
- **
- *******************************************************************************/
- public Serializable getRecordPrimaryKey()
- {
- return recordPrimaryKey;
- }
-
-
-
- /*******************************************************************************
- ** Setter for recordPrimaryKey
- **
- *******************************************************************************/
- public void setRecordPrimaryKey(Serializable recordPrimaryKey)
- {
- this.recordPrimaryKey = recordPrimaryKey;
- }
-
-
-
- /*******************************************************************************
- ** Fluent setter for recordPrimaryKey
- **
- *******************************************************************************/
- public TestScriptInput withRecordPrimaryKey(Serializable recordPrimaryKey)
- {
- this.recordPrimaryKey = recordPrimaryKey;
- return (this);
- }
-
-
-
/*******************************************************************************
** Getter for inputValues
**
*******************************************************************************/
- public Map getInputValues()
+ public Map getInputValues()
{
return inputValues;
}
@@ -99,7 +64,7 @@ public class TestScriptInput extends AbstractTableActionInput
** Setter for inputValues
**
*******************************************************************************/
- public void setInputValues(Map inputValues)
+ public void setInputValues(Map inputValues)
{
this.inputValues = inputValues;
}
@@ -110,7 +75,7 @@ public class TestScriptInput extends AbstractTableActionInput
** Fluent setter for inputValues
**
*******************************************************************************/
- public TestScriptInput withInputValues(Map inputValues)
+ public TestScriptInput withInputValues(Map inputValues)
{
this.inputValues = inputValues;
return (this);
@@ -119,68 +84,34 @@ public class TestScriptInput extends AbstractTableActionInput
/*******************************************************************************
- ** Getter for code
+ ** Getter for codeReference
**
*******************************************************************************/
- public String getCode()
+ public QCodeReference getCodeReference()
{
- return code;
+ return codeReference;
}
/*******************************************************************************
- ** Setter for code
+ ** Setter for codeReference
**
*******************************************************************************/
- public void setCode(String code)
+ public void setCodeReference(QCodeReference codeReference)
{
- this.code = code;
+ this.codeReference = codeReference;
}
/*******************************************************************************
- ** Fluent setter for code
+ ** Fluent setter for codeReference
**
*******************************************************************************/
- public TestScriptInput withCode(String code)
+ public TestScriptInput withCodeReference(QCodeReference codeReference)
{
- this.code = code;
- return (this);
- }
-
-
-
- /*******************************************************************************
- ** Getter for scriptTypeId
- **
- *******************************************************************************/
- public Serializable getScriptTypeId()
- {
- return scriptTypeId;
- }
-
-
-
- /*******************************************************************************
- ** Setter for scriptTypeId
- **
- *******************************************************************************/
- public void setScriptTypeId(Serializable scriptTypeId)
- {
- this.scriptTypeId = scriptTypeId;
- }
-
-
-
- /*******************************************************************************
- ** Fluent setter for scriptTypeId
- **
- *******************************************************************************/
- public TestScriptInput withScriptTypeId(Serializable scriptTypeId)
- {
- this.scriptTypeId = scriptTypeId;
+ this.codeReference = codeReference;
return (this);
}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/actions/scripts/TestScriptOutput.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/actions/scripts/TestScriptOutput.java
index d6da9222..e9641dc6 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/actions/scripts/TestScriptOutput.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/actions/scripts/TestScriptOutput.java
@@ -22,7 +22,10 @@
package com.kingsrook.qqq.backend.core.model.actions.scripts;
+import java.io.Serializable;
+import java.util.List;
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionOutput;
+import com.kingsrook.qqq.backend.core.model.data.QRecord;
/*******************************************************************************
@@ -30,4 +33,103 @@ import com.kingsrook.qqq.backend.core.model.actions.AbstractActionOutput;
*******************************************************************************/
public class TestScriptOutput extends AbstractActionOutput
{
+ private Serializable outputObject;
+ private Exception exception;
+ private QRecord scriptLog;
+ private List scriptLogLines;
+
+
+
+ /*******************************************************************************
+ ** Getter for outputObject
+ **
+ *******************************************************************************/
+ public Serializable getOutputObject()
+ {
+ return outputObject;
+ }
+
+
+
+ /*******************************************************************************
+ ** Setter for outputObject
+ **
+ *******************************************************************************/
+ public void setOutputObject(Serializable outputObject)
+ {
+ this.outputObject = outputObject;
+ }
+
+
+
+ /*******************************************************************************
+ ** Fluent setter for outputObject
+ **
+ *******************************************************************************/
+ public TestScriptOutput withOutputObject(Serializable outputObject)
+ {
+ this.outputObject = outputObject;
+ return (this);
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public void setException(Exception exception)
+ {
+ this.exception = exception;
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public Exception getException()
+ {
+ return exception;
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public void setScriptLog(QRecord scriptLog)
+ {
+ this.scriptLog = scriptLog;
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public QRecord getScriptLog()
+ {
+ return scriptLog;
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public void setScriptLogLines(List scriptLogLines)
+ {
+ this.scriptLogLines = scriptLogLines;
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public List getScriptLogLines()
+ {
+ return scriptLogLines;
+ }
+
}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/code/QCodeUsage.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/code/QCodeUsage.java
index ce4509be..1020dedb 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/code/QCodeUsage.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/code/QCodeUsage.java
@@ -32,5 +32,6 @@ public enum QCodeUsage
CUSTOMIZER, // a function to customize part of a QQQ table's behavior
POSSIBLE_VALUE_PROVIDER, // code that drives a custom possibleValueSource
RECORD_AUTOMATION_HANDLER, // code that executes record automations
- REPORT_STATIC_DATA_SUPPLIER // code that supplies static data to a report
+ REPORT_STATIC_DATA_SUPPLIER, // code that supplies static data to a report
+ SCRIPT_TESTER // class that is used to test scripts.
}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/fields/AdornmentType.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/fields/AdornmentType.java
index ad5f3c53..00a3c5d8 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/fields/AdornmentType.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/fields/AdornmentType.java
@@ -98,4 +98,20 @@ public enum AdornmentType
String XLARGE = "xlarge";
}
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public interface CodeEditorValues
+ {
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ static Pair languageMode(String languageMode)
+ {
+ return (new Pair<>("languageMode", languageMode));
+ }
+ }
+
}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/tables/AssociatedScript.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/tables/AssociatedScript.java
index 1645e470..3a8766c3 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/tables/AssociatedScript.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/metadata/tables/AssociatedScript.java
@@ -23,6 +23,7 @@ package com.kingsrook.qqq.backend.core.model.metadata.tables;
import java.io.Serializable;
+import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
/*******************************************************************************
@@ -30,8 +31,9 @@ import java.io.Serializable;
*******************************************************************************/
public class AssociatedScript implements Serializable
{
- private String fieldName;
- private Serializable scriptTypeId;
+ private String fieldName;
+ private Serializable scriptTypeId;
+ private QCodeReference scriptTester;
@@ -101,4 +103,38 @@ public class AssociatedScript implements Serializable
return (this);
}
+
+
+ /*******************************************************************************
+ ** Getter for scriptTester
+ **
+ *******************************************************************************/
+ public QCodeReference getScriptTester()
+ {
+ return scriptTester;
+ }
+
+
+
+ /*******************************************************************************
+ ** Setter for scriptTester
+ **
+ *******************************************************************************/
+ public void setScriptTester(QCodeReference scriptTester)
+ {
+ this.scriptTester = scriptTester;
+ }
+
+
+
+ /*******************************************************************************
+ ** Fluent setter for scriptTester
+ **
+ *******************************************************************************/
+ public AssociatedScript withScriptTester(QCodeReference scriptTester)
+ {
+ this.scriptTester = scriptTester;
+ return (this);
+ }
+
}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/Script.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/Script.java
index 42fb6fe9..232938d3 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/Script.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/Script.java
@@ -36,13 +36,13 @@ public class Script extends QRecordEntity
{
public static final String TABLE_NAME = "script";
- @QField()
+ @QField(isEditable = false)
private Integer id;
- @QField()
+ @QField(isEditable = false)
private Instant createDate;
- @QField()
+ @QField(isEditable = false)
private Instant modifyDate;
@QField()
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptLog.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptLog.java
index 5949f326..71cbf7e5 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptLog.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptLog.java
@@ -35,13 +35,13 @@ public class ScriptLog extends QRecordEntity
{
public static final String TABLE_NAME = "scriptLog";
- @QField()
+ @QField(isEditable = false)
private Integer id;
- @QField()
+ @QField(isEditable = false)
private Instant createDate;
- @QField()
+ @QField(isEditable = false)
private Instant modifyDate;
@QField(possibleValueSourceName = "script")
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptLogLine.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptLogLine.java
index f878e91b..d9d7f19b 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptLogLine.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptLogLine.java
@@ -34,13 +34,13 @@ public class ScriptLogLine extends QRecordEntity
{
public static final String TABLE_NAME = "scriptLogLine";
- @QField()
+ @QField(isEditable = false)
private Integer id;
- @QField()
+ @QField(isEditable = false)
private Instant createDate;
- @QField()
+ @QField(isEditable = false)
private Instant modifyDate;
@QField(possibleValueSourceName = "scriptLog")
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptRevision.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptRevision.java
index ff8f0d26..0169c561 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptRevision.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptRevision.java
@@ -36,13 +36,13 @@ public class ScriptRevision extends QRecordEntity
{
public static final String TABLE_NAME = "scriptRevision";
- @QField()
+ @QField(isEditable = false)
private Integer id;
- @QField()
+ @QField(isEditable = false)
private Instant createDate;
- @QField()
+ @QField(isEditable = false)
private Instant modifyDate;
@QField(possibleValueSourceName = "script")
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptType.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptType.java
index 6b50d26e..e2fe2354 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptType.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptType.java
@@ -34,13 +34,13 @@ public class ScriptType extends QRecordEntity
{
public static final String TABLE_NAME = "scriptType";
- @QField()
+ @QField(isEditable = false)
private Integer id;
- @QField()
+ @QField(isEditable = false)
private Instant createDate;
- @QField()
+ @QField(isEditable = false)
private Instant modifyDate;
@QField()
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptsMetaDataProvider.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptsMetaDataProvider.java
index 39c2249d..ac671f61 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptsMetaDataProvider.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/model/scripts/ScriptsMetaDataProvider.java
@@ -163,7 +163,8 @@ public class ScriptsMetaDataProvider
.withSection(new QFieldSection("identity", new QIcon().withName("badge"), Tier.T1, List.of("id", "name")))
.withSection(new QFieldSection("details", new QIcon().withName("dataset"), Tier.T2, List.of("helpText", "sampleCode")))
.withSection(new QFieldSection("dates", new QIcon().withName("calendar_month"), Tier.T3, List.of("createDate", "modifyDate")));
- tableMetaData.getField("sampleCode").withFieldAdornment(new FieldAdornment(AdornmentType.CODE_EDITOR));
+ tableMetaData.getField("sampleCode").withFieldAdornment(new FieldAdornment(AdornmentType.CODE_EDITOR).withValue(AdornmentType.CodeEditorValues.languageMode("javascript")));
+ tableMetaData.getField("helpText").withFieldAdornment(new FieldAdornment(AdornmentType.CODE_EDITOR).withValue(AdornmentType.CodeEditorValues.languageMode("text")));
return (tableMetaData);
}
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/etl/basic/BasicETLExtractFunction.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/etl/basic/BasicETLExtractFunction.java
index 9b0d0687..70317044 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/etl/basic/BasicETLExtractFunction.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/etl/basic/BasicETLExtractFunction.java
@@ -52,7 +52,7 @@ public class BasicETLExtractFunction implements BackendStep
public void run(RunBackendStepInput runBackendStepInput, RunBackendStepOutput runBackendStepOutput) throws QException
{
String tableName = runBackendStepInput.getValueString(BasicETLProcess.FIELD_SOURCE_TABLE);
- LOG.info("Start query on table: " + tableName);
+ LOG.debug("Start query on table: " + tableName);
QueryInput queryInput = new QueryInput(runBackendStepInput.getInstance());
queryInput.setSession(runBackendStepInput.getSession());
@@ -70,7 +70,7 @@ public class BasicETLExtractFunction implements BackendStep
//////////////////////////////////////////////////////////////////////
// if the caller gave us a record pipe, pass it to the query action //
//////////////////////////////////////////////////////////////////////
- if (recordPipe != null)
+ if(recordPipe != null)
{
queryInput.setRecordPipe(recordPipe);
}
@@ -78,7 +78,7 @@ public class BasicETLExtractFunction implements BackendStep
QueryAction queryAction = new QueryAction();
QueryOutput queryOutput = queryAction.execute(queryInput);
- if (recordPipe == null)
+ if(recordPipe == null)
{
////////////////////////////////////////////////////////////////////////////
// only return the records (and log about them) if there's no record pipe //
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/etl/basic/BasicETLLoadFunction.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/etl/basic/BasicETLLoadFunction.java
index d0a6c77b..68dbb512 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/etl/basic/BasicETLLoadFunction.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/etl/basic/BasicETLLoadFunction.java
@@ -60,13 +60,14 @@ public class BasicETLLoadFunction implements BackendStep
// exit early with no-op if no records made it here //
//////////////////////////////////////////////////////
List inputRecords = runBackendStepInput.getRecords();
- LOG.info("Received [" + inputRecords.size() + "] records to load");
if(CollectionUtils.nullSafeIsEmpty(inputRecords))
{
runBackendStepOutput.addValue(BasicETLProcess.FIELD_RECORD_COUNT, 0);
return;
}
+ LOG.info("Received [" + inputRecords.size() + "] records to load");
+
//////////////////////////////////////////////////////////////////
// put the destination table name in all records being inserted //
//////////////////////////////////////////////////////////////////
diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/etl/basic/BasicETLTransformFunction.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/etl/basic/BasicETLTransformFunction.java
index 42e90231..6ef8f44d 100644
--- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/etl/basic/BasicETLTransformFunction.java
+++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/processes/implementations/etl/basic/BasicETLTransformFunction.java
@@ -59,21 +59,21 @@ public class BasicETLTransformFunction implements BackendStep
public void run(RunBackendStepInput runBackendStepInput, RunBackendStepOutput runBackendStepOutput) throws QException
{
String tableName = runBackendStepInput.getValueString(BasicETLProcess.FIELD_DESTINATION_TABLE);
- LOG.info("Start transform for destination table: " + tableName);
+ LOG.debug("Start transform for destination table: " + tableName);
////////////////////////////////////////////////////////////////////////////////////////////
// exit early with no-op if no records made it here, or if we don't have a mapping to use //
////////////////////////////////////////////////////////////////////////////////////////////
if(CollectionUtils.nullSafeIsEmpty(runBackendStepInput.getRecords()))
{
- LOG.info("Exiting early with no-op for empty input record list.");
+ LOG.debug("Exiting early with no-op for empty input record list.");
return;
}
String mappingJSON = runBackendStepInput.getValueString(BasicETLProcess.FIELD_MAPPING_JSON);
if(!StringUtils.hasContent(mappingJSON))
{
- LOG.info("Exiting early with no-op for empty mappingJSON.");
+ LOG.debug("Exiting early with no-op for empty mappingJSON.");
return;
}
diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/scripts/TestScriptActionInterfaceTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/scripts/TestScriptActionInterfaceTest.java
new file mode 100644
index 00000000..28627695
--- /dev/null
+++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/actions/scripts/TestScriptActionInterfaceTest.java
@@ -0,0 +1,222 @@
+/*
+ * 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.scripts;
+
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import com.kingsrook.qqq.backend.core.exceptions.QException;
+import com.kingsrook.qqq.backend.core.model.actions.scripts.ExecuteCodeInput;
+import com.kingsrook.qqq.backend.core.model.actions.scripts.TestScriptInput;
+import com.kingsrook.qqq.backend.core.model.actions.scripts.TestScriptOutput;
+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.code.QCodeUsage;
+import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData;
+import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType;
+import com.kingsrook.qqq.backend.core.model.session.QSession;
+import com.kingsrook.qqq.backend.core.utils.TestUtils;
+import com.kingsrook.qqq.backend.core.utils.ValueUtils;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+
+/*******************************************************************************
+ ** Unit test for TestScriptActionInterface
+ *******************************************************************************/
+class TestScriptActionInterfaceTest
+{
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ @Test
+ void test() throws QException
+ {
+ QInstance qInstance = TestUtils.defineInstance();
+
+ TestScriptInput testScriptInput = new TestScriptInput(qInstance);
+ testScriptInput.setSession(new QSession());
+ testScriptInput.setInputValues(Map.of("name", "Darin", "age", 42));
+ testScriptInput.setCodeReference(new QCodeReference(SampleScript.class, QCodeUsage.CUSTOMIZER));
+ TestScriptOutput testScriptOutput = new TestScriptOutput();
+ new SampleTestAction().execute(testScriptInput, testScriptOutput);
+
+ assertNull(testScriptOutput.getException());
+ assertTrue(testScriptOutput.getOutputObject() instanceof SampleTestOutput);
+ SampleTestOutput sampleTestOutput = (SampleTestOutput) testScriptOutput.getOutputObject();
+ assertEquals("Darin is 42 years old!", sampleTestOutput.getMessage());
+ }
+
+
+
+ /*******************************************************************************
+ **
+ *******************************************************************************/
+ public static class SampleScript implements Function