mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
Script Tests and further enhancements
This commit is contained in:
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<QFieldMetaData> 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<QFieldMetaData> 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());
|
||||
}
|
||||
|
||||
}
|
@ -230,7 +230,7 @@ public class QInstanceEnricher
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private void enrichField(QFieldMetaData field)
|
||||
public void enrichField(QFieldMetaData field)
|
||||
{
|
||||
if(!StringUtils.hasContent(field.getLabel()))
|
||||
{
|
||||
|
@ -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<String, String> inputValues;
|
||||
private Map<String, Serializable> 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<String, String> getInputValues()
|
||||
public Map<String, Serializable> getInputValues()
|
||||
{
|
||||
return inputValues;
|
||||
}
|
||||
@ -99,7 +64,7 @@ public class TestScriptInput extends AbstractTableActionInput
|
||||
** Setter for inputValues
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setInputValues(Map<String, String> inputValues)
|
||||
public void setInputValues(Map<String, Serializable> inputValues)
|
||||
{
|
||||
this.inputValues = inputValues;
|
||||
}
|
||||
@ -110,7 +75,7 @@ public class TestScriptInput extends AbstractTableActionInput
|
||||
** Fluent setter for inputValues
|
||||
**
|
||||
*******************************************************************************/
|
||||
public TestScriptInput withInputValues(Map<String, String> inputValues)
|
||||
public TestScriptInput withInputValues(Map<String, Serializable> 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);
|
||||
}
|
||||
|
||||
|
@ -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<QRecord> 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<QRecord> scriptLogLines)
|
||||
{
|
||||
this.scriptLogLines = scriptLogLines;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<QRecord> getScriptLogLines()
|
||||
{
|
||||
return scriptLogLines;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.
|
||||
}
|
||||
|
@ -98,4 +98,20 @@ public enum AdornmentType
|
||||
String XLARGE = "xlarge";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public interface CodeEditorValues
|
||||
{
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
static Pair<String, Serializable> languageMode(String languageMode)
|
||||
{
|
||||
return (new Pair<>("languageMode", languageMode));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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")
|
||||
|
@ -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")
|
||||
|
@ -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")
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 //
|
||||
|
@ -60,13 +60,14 @@ public class BasicETLLoadFunction implements BackendStep
|
||||
// exit early with no-op if no records made it here //
|
||||
//////////////////////////////////////////////////////
|
||||
List<QRecord> 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 //
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<Map<String, Object>, Serializable>
|
||||
{
|
||||
@Override
|
||||
public Serializable apply(Map<String, Object> context)
|
||||
{
|
||||
SampleTestInput input = (SampleTestInput) context.get("input");
|
||||
SampleTestOutput output = (SampleTestOutput) context.get("output");
|
||||
output.setMessage(input.getName() + " is " + input.getAge() + " years old!");
|
||||
return (output);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static class SampleTestAction implements TestScriptActionInterface
|
||||
{
|
||||
@Override
|
||||
public void setupTestScriptInput(TestScriptInput testScriptInput, ExecuteCodeInput executeCodeInput)
|
||||
{
|
||||
SampleTestInput sampleTestInput = new SampleTestInput();
|
||||
sampleTestInput.setName(ValueUtils.getValueAsString(testScriptInput.getInputValues().get("name")));
|
||||
sampleTestInput.setAge(ValueUtils.getValueAsInteger(testScriptInput.getInputValues().get("age")));
|
||||
executeCodeInput.setInput(Map.of("input", sampleTestInput));
|
||||
|
||||
executeCodeInput.getContext().put("output", new SampleTestOutput());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public List<QFieldMetaData> getTestInputFields()
|
||||
{
|
||||
return List.of(
|
||||
new QFieldMetaData("name", QFieldType.STRING),
|
||||
new QFieldMetaData("age", QFieldType.INTEGER)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public List<QFieldMetaData> getTestOutputFields()
|
||||
{
|
||||
return List.of(new QFieldMetaData("message", QFieldType.STRING));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static class SampleTestInput implements Serializable
|
||||
{
|
||||
private String name;
|
||||
private Integer age;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for name
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for name
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for age
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Integer getAge()
|
||||
{
|
||||
return age;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for age
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setAge(Integer age)
|
||||
{
|
||||
this.age = age;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static class SampleTestOutput implements Serializable
|
||||
{
|
||||
private String message;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for message
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getMessage()
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for message
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setMessage(String message)
|
||||
{
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,52 +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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.backend.core.actions.scripts;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
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.utils.TestUtils;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Unit test for TestScriptAction
|
||||
*******************************************************************************/
|
||||
class TestScriptActionTest
|
||||
{
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
@Disabled("Not yet done.")
|
||||
void test() throws QException
|
||||
{
|
||||
QInstance instance = TestUtils.defineInstance();
|
||||
TestScriptInput input = new TestScriptInput(instance);
|
||||
TestScriptOutput output = new TestScriptOutput();
|
||||
new TestScriptAction().run(input, output);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user