diff --git a/src/Tools/AI Test Toolkit/src/AITTestContext.Codeunit.al b/src/Tools/AI Test Toolkit/src/AITTestContext.Codeunit.al index b168b50b7a..9a7deb7128 100644 --- a/src/Tools/AI Test Toolkit/src/AITTestContext.Codeunit.al +++ b/src/Tools/AI Test Toolkit/src/AITTestContext.Codeunit.al @@ -84,6 +84,16 @@ codeunit 149044 "AIT Test Context" exit(AITTestContextImpl.GetExpectedData()); end; + /// + /// Gets the continue on failure flag for the current turn. + /// If the flag is not set in the test input, it defaults to false. + /// + /// True if the eval should continue on failure, false otherwise. + procedure GetCanContinueOnFailure(): Boolean + begin + exit(AITTestContextImpl.GetCanContinueOnFailure()); + end; + /// /// Sets the answer for a question and answer evaluation. /// This will also copy the context, question and ground truth to the output dataset. @@ -204,6 +214,34 @@ codeunit 149044 "AIT Test Context" AITTestContextImpl.SetTokenConsumption(TokensUsed); end; + /// + /// Gets the per-suite setup data as a Test Input Json. + /// The consuming test app must have imported a YAML file with the suite_setup token. + /// + /// Test Input Json containing the suite setup data. + procedure GetEvalSuiteSetupDataInput(): Codeunit "Test Input Json" + begin + exit(AITTestContextImpl.GetEvalSuiteSetupDataInput()); + end; + + /// + /// Marks the per-suite setup as completed on the test suite record. + /// Call this after your suite setup logic has finished successfully. + /// + procedure SetEvalSuiteSetupCompleted() + begin + AITTestContextImpl.SetEvalSuiteSetupCompleted(); + end; + + /// + /// Checks if the per-suite setup has been marked as done on the test suite record. + /// + /// True if suite setup has been executed. + procedure IsSuiteSetupDone(): Boolean + begin + exit(AITTestContextImpl.IsSuiteSetupDone()); + end; + /// /// Integration event that is raised after an eval run is completed. /// diff --git a/src/Tools/AI Test Toolkit/src/AITTestContextImpl.Codeunit.al b/src/Tools/AI Test Toolkit/src/AITTestContextImpl.Codeunit.al index bf0807c649..15b1f8cf5c 100644 --- a/src/Tools/AI Test Toolkit/src/AITTestContextImpl.Codeunit.al +++ b/src/Tools/AI Test Toolkit/src/AITTestContextImpl.Codeunit.al @@ -18,6 +18,7 @@ codeunit 149043 "AIT Test Context Impl." var AITTestSuiteMgt: Codeunit "AIT Test Suite Mgt."; GlobalTestOutputJson: Codeunit "Test Output Json"; + GlobalSuiteSetupJson: Codeunit "Test Input Json"; GlobalAccuracy: Decimal; CurrentTurn: Integer; NumberOfTurns: Integer; @@ -29,6 +30,7 @@ codeunit 149043 "AIT Test Context Impl." ContextTok: Label 'context', Locked = true; GroundTruthTok: Label 'ground_truth', Locked = true; ExpectedDataTok: Label 'expected_data', Locked = true; + ContinueOnFailureTok: Label 'continue_on_failure', Locked = true; TestMetricsTok: Label 'test_metrics', Locked = true; TestSetupTok: Label 'test_setup', Locked = true; QuestionTok: Label 'question', Locked = true; @@ -39,6 +41,9 @@ codeunit 149043 "AIT Test Context Impl." RoleTok: Label 'role', Locked = true; ContentTok: Label 'content', Locked = true; ConversationTok: Label 'conversation', Locked = true; + HasSuiteSetupData: Boolean; + SuiteSetupDataNotLoadedErr: Label 'Per-suite setup data has not been loaded.'; + SuiteSetupInputCodeTok: Label 'SUITE-SETUP', Locked = true; /// /// Returns the Test Input value as Test Input Json Codeunit from the input dataset for the current iteration. @@ -97,6 +102,23 @@ codeunit 149043 "AIT Test Context Impl." exit(GetTestInput(ExpectedDataTok)); end; + /// + /// Gets the continue on failure flag for the current turn. + /// If the flag is not set in the test input, it defaults to false. + /// + /// True if the eval should continue on failure, false otherwise. + procedure GetCanContinueOnFailure(): Boolean + var + ContinueOnFailureInput: Codeunit "Test Input Json"; + ElementFound: Boolean; + begin + ContinueOnFailureInput := GetTestInput(ContinueOnFailureTok, ElementFound); + if not ElementFound then + exit(false); + + exit(ContinueOnFailureInput.ValueAsBoolean()); + end; + /// /// Sets the answer for a question and answer evaluation. /// This will also copy the context, question and ground truth to the output dataset. @@ -332,6 +354,58 @@ codeunit 149043 "AIT Test Context Impl." NumberOfTurns := TurnsInputJson.GetElementCount() else NumberOfTurns := 1; + + if not HasSuiteSetupData then + LoadSuiteSetupFromDataset(); + end; + + /// + /// Loads suite setup data from the dataset referenced by the current test's Test Input Group. + /// Resolves language variants using the suite's Run Language ID. + /// + local procedure LoadSuiteSetupFromDataset() + var + SuiteSetupGroup: Record "Test Input Group"; + AITTestSuite: Record "AIT Test Suite"; + TestInputCU: Codeunit "Test Input"; + AITTestSuiteLanguage: Codeunit "AIT Test Suite Language"; + SuiteSetupInputJson: Codeunit "Test Input Json"; + ResolvedDatasetCode: Code[100]; + begin + if not GetSuiteSetupGroup(SuiteSetupGroup) then + exit; + + GetAITTestSuite(AITTestSuite); + ResolvedDatasetCode := AITTestSuiteLanguage.GetLanguageDataset(SuiteSetupGroup.Code, AITTestSuite."Run Language ID"); + SuiteSetupInputJson := TestInputCU.GetTestInputByCode(ResolvedDatasetCode, SuiteSetupInputCodeTok); + + if SuiteSetupInputJson.ToText() = '' then + exit; + + ImportSuiteSetupData(SuiteSetupInputJson.AsJsonToken()); + end; + + /// + /// Finds the suite setup Test Input Group for the current test's dataset. + /// Navigates: AITTestMethodLine."Input Dataset" → TestInputGroup."Suite Setup Group Name" → target group. + /// + local procedure GetSuiteSetupGroup(var SuiteSetupGroup: Record "Test Input Group"): Boolean + var + AITTestMethodLine: Record "AIT Test Method Line"; + DatasetGroup: Record "Test Input Group"; + begin + GetAITTestMethodLine(AITTestMethodLine); + if AITTestMethodLine."Input Dataset" = '' then + exit(false); + + if not DatasetGroup.Get(AITTestMethodLine."Input Dataset") then + exit(false); + + if DatasetGroup."Suite Setup Group Name" = '' then + exit(false); + + SuiteSetupGroup.SetRange("Group Name", DatasetGroup."Suite Setup Group Name"); + exit(SuiteSetupGroup.FindFirst()); end; /// @@ -349,6 +423,22 @@ codeunit 149043 "AIT Test Context Impl." TestInputJson := TestInput.GetTestInput(ElementName); end; + /// + /// Gets the test input for the provided element, returning whether the element was found. + /// + /// Element name to get from test input. + /// Set to true if the element exists. + /// Test Input Json for the element + local procedure GetTestInput(ElementName: Text; var ElementFound: Boolean) TestInputJson: Codeunit "Test Input Json" + var + TestInput: Codeunit "Test Input"; + begin + if IsMultiTurn then + TestInputJson := TestInput.GetTestInput(TurnsTok).ElementAt(CurrentTurn - 1).ElementExists(ElementName, ElementFound) + else + TestInputJson := TestInput.GetTestInput().ElementExists(ElementName, ElementFound); + end; + /// /// Adds a message to the test output for the current iteration. /// @@ -411,6 +501,52 @@ codeunit 149043 "AIT Test Context Impl." CurrentTestOutputJson.Add(ElementName, TestInput.GetTestInput(ElementName).ValueAsText()); end; + /// + /// Sets the per-suite setup data from a parsed JSON token. + /// + /// The JSON token containing the parsed suite setup data. + internal procedure ImportSuiteSetupData(SuiteSetupJsonToken: JsonToken) + begin + GlobalSuiteSetupJson.Initialize(SuiteSetupJsonToken); + HasSuiteSetupData := true; + end; + + /// + /// Gets the per-suite setup data as a Test Input Json. + /// + /// Test Input Json containing the suite setup data. + procedure GetEvalSuiteSetupDataInput(): Codeunit "Test Input Json" + begin + if not HasSuiteSetupData then + Error(SuiteSetupDataNotLoadedErr); + exit(GlobalSuiteSetupJson); + end; + + /// + /// Marks the per-suite setup as completed on the suite setup test input group. + /// + procedure SetEvalSuiteSetupCompleted() + var + SuiteSetupGroup: Record "Test Input Group"; + begin + if GetSuiteSetupGroup(SuiteSetupGroup) then + SuiteSetupGroup.SetSuiteSetupDone(); + end; + + /// + /// Checks if the per-suite setup has been marked as done on the suite setup test input group. + /// + /// True if suite setup has been executed. + procedure IsSuiteSetupDone(): Boolean + var + SuiteSetupGroup: Record "Test Input Group"; + begin + if not GetSuiteSetupGroup(SuiteSetupGroup) then + exit(false); + + exit(SuiteSetupGroup."Suite Setup Done"); + end; + /// /// Sets the token consumption for the method line run. Useful if external calls are made outside of AI toolkit. /// diff --git a/src/Tools/AI Test Toolkit/src/TestSuite/AITALTestSuiteMgt.Codeunit.al b/src/Tools/AI Test Toolkit/src/TestSuite/AITALTestSuiteMgt.Codeunit.al index a7c6ebde3d..869cafd457 100644 --- a/src/Tools/AI Test Toolkit/src/TestSuite/AITALTestSuiteMgt.Codeunit.al +++ b/src/Tools/AI Test Toolkit/src/TestSuite/AITALTestSuiteMgt.Codeunit.al @@ -17,6 +17,7 @@ codeunit 149037 "AIT AL Test Suite Mgt" var RunProcedureOperationTok: Label 'Run Procedure', Locked = true; AITTestSuitePrefixTok: Label 'AIT-', Locked = true; + InvalidSuiteSetupYamlErr: Label 'The per-suite setup content is not valid YAML.'; internal procedure GetDefaultRunProcedureOperationLbl(): Text begin @@ -224,6 +225,22 @@ codeunit 149037 "AIT AL Test Suite Mgt" exit(OutputJsonArray); end; + /// + /// Import per-suite setup data from YAML content. + /// The YAML is parsed and stored for access via AITTestContext.GetSuiteSetupData(). + /// + /// The YAML content as text. + procedure ImportSuiteSetupData(SuiteSetupYamlContent: Text) + var + AITTestContextImpl: Codeunit "AIT Test Context Impl."; + SuiteSetupDataJsonObj: JsonObject; + begin + if not SuiteSetupDataJsonObj.ReadFromYaml(SuiteSetupYamlContent) then + Error(InvalidSuiteSetupYamlErr); + + AITTestContextImpl.ImportSuiteSetupData(SuiteSetupDataJsonObj.AsToken()); + end; + /// /// Import the Test Input Dataset from an InStream of a dataset in a supported format. /// Overwrite the dataset if the dataset with same filename is already imported by the same app diff --git a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLines.Page.al b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLines.Page.al index 5034971f03..ae7c31fb63 100644 --- a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLines.Page.al +++ b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLines.Page.al @@ -5,6 +5,8 @@ namespace System.TestTools.AITestToolkit; +using System.TestTools.TestRunner; + page 149034 "AIT Test Method Lines" { Caption = 'Evals'; @@ -239,6 +241,32 @@ page 149034 "AIT Test Method Lines" CurrPage.Update(false); end; } + action(ResetSuiteSetup) + { + Caption = 'Reset Suite Setup'; + ToolTip = 'Resets the per-suite setup flag so that the setup data can be created again.'; + Image = ResetStatus; + + trigger OnAction() + var + TestInputGroup: Record "Test Input Group"; + SuiteSetupGroup: Record "Test Input Group"; + InputDatasetCode: Code[100]; + begin + InputDatasetCode := Rec.GetTestInputCode(); + if not TestInputGroup.Get(InputDatasetCode) then + exit; + + if TestInputGroup."Suite Setup Group Name" = '' then + exit; + + SuiteSetupGroup.SetRange("Group Name", TestInputGroup."Suite Setup Group Name"); + if SuiteSetupGroup.FindFirst() then begin + SuiteSetupGroup.ResetSuiteSetup(); + CurrPage.Update(false); + end; + end; + } action(LogEntries) { Caption = 'Log Entries'; diff --git a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Page.al b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Page.al index 371ce3d411..a1a65bfc97 100644 --- a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Page.al +++ b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Page.al @@ -347,6 +347,18 @@ page 149031 "AIT Test Suite" end; } + action(ResetSuiteSetup) + { + Caption = 'Reset Suite Setup'; + ToolTip = 'Resets the per-suite setup flag so that the setup can be run again.'; + Image = ResetStatus; + + trigger OnAction() + begin + Rec.ResetSuiteSetup(); + CurrPage.Update(false); + end; + } action(Compare) { Caption = 'View runs'; diff --git a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Table.al b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Table.al index 092e268591..b818f13b7d 100644 --- a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Table.al +++ b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Table.al @@ -298,6 +298,22 @@ table 149030 "AIT Test Suite" exit(AITTestSuiteLanguage.GetLanguageDataset(Rec."Input Dataset", Rec."Run Language ID")); end; + internal procedure ResetSuiteSetup() + var + TestInputGroup: Record "Test Input Group"; + SuiteSetupGroup: Record "Test Input Group"; + begin + if not TestInputGroup.Get(Rec."Input Dataset") then + exit; + + if TestInputGroup."Suite Setup Group Name" = '' then + exit; + + SuiteSetupGroup.SetRange("Group Name", TestInputGroup."Suite Setup Group Name"); + if SuiteSetupGroup.FindFirst() then + SuiteSetupGroup.ResetSuiteSetup(); + end; + var BaseVersionMustBeLessThanVersionErr: Label 'Base Version must be less than or equal to Version'; } diff --git a/src/Tools/Test Framework/Test Runner/src/ALTestSuite.Table.al b/src/Tools/Test Framework/Test Runner/src/ALTestSuite.Table.al index d375666665..a54af1de9b 100644 --- a/src/Tools/Test Framework/Test Runner/src/ALTestSuite.Table.al +++ b/src/Tools/Test Framework/Test Runner/src/ALTestSuite.Table.al @@ -115,5 +115,6 @@ table 130451 "AL Test Suite" if "Test Runner Id" = 0 then "Test Runner Id" := TestRunnerMgt.GetDefaultTestRunner(); end; + } diff --git a/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInput.Codeunit.al b/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInput.Codeunit.al index 10cf5c60c0..d76464e31d 100644 --- a/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInput.Codeunit.al +++ b/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInput.Codeunit.al @@ -66,6 +66,22 @@ codeunit 130460 "Test Input" exit(DataPerTest.GetInput(DataPerTest)); end; + procedure GetTestInputByCode(GroupCode: Code[100]; InputCode: Code[100]): Codeunit "Test Input Json" + var + TestInputRec: Record "Test Input"; + TestInputJson: Codeunit "Test Input Json"; + InputContent: Text; + begin + if not TestInputRec.Get(GroupCode, InputCode) then + exit(TestInputJson); + + InputContent := TestInputRec.GetInput(TestInputRec); + if InputContent <> '' then + TestInputJson.Initialize(InputContent); + + exit(TestInputJson); + end; + var DataPerTest: Record "Test Input"; DataPerTestTestInput: Codeunit "Test Input Json"; diff --git a/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInput.Page.al b/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInput.Page.al index dd9a522edc..02339c890d 100644 --- a/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInput.Page.al +++ b/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInput.Page.al @@ -50,6 +50,10 @@ page 130457 "Test Input" { Editable = false; } + field("Suite Setup Done"; Rec."Suite Setup Done") + { + Importance = Additional; + } } part(TestInputPart; "Test Input Part") { diff --git a/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInputGroup.Table.al b/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInputGroup.Table.al index 988c6454ba..d82df9a631 100644 --- a/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInputGroup.Table.al +++ b/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInputGroup.Table.al @@ -113,6 +113,18 @@ table 130454 "Test Input Group" ToolTip = 'Specifies the AppId from which the test input group was imported.'; DataClassification = SystemMetadata; } + field(80; "Suite Setup Done"; Boolean) + { + Caption = 'Suite Setup Done'; + ToolTip = 'Specifies whether the per-suite setup has been executed for this test input group.'; + DataClassification = SystemMetadata; + } + field(81; "Suite Setup Group Name"; Text[250]) + { + Caption = 'Suite Setup Group Name'; + ToolTip = 'Specifies the group name of the test input group that contains suite setup data for this dataset.'; + DataClassification = CustomerContent; + } } keys { @@ -218,6 +230,18 @@ table 130454 "Test Input Group" ValidateGroups(); end; + procedure SetSuiteSetupDone() + begin + Rec."Suite Setup Done" := true; + Rec.Modify(true); + end; + + procedure ResetSuiteSetup() + begin + Rec."Suite Setup Done" := false; + Rec.Modify(true); + end; + procedure GetTestInputGroupLanguages(TestInputCode: Code[100]; var LanguageVersions: Record "Test Input Group"): Boolean begin LanguageVersions.Reset(); diff --git a/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInputGroups.Page.al b/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInputGroups.Page.al index dae881fa9e..eeadf026e9 100644 --- a/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInputGroups.Page.al +++ b/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInputGroups.Page.al @@ -67,6 +67,28 @@ page 130462 "Test Input Groups" { area(Processing) { + action(DeleteSelected) + { + Caption = 'Delete Selected'; + ToolTip = 'Delete the selected test input groups and their entries.'; + Image = Delete; + Scope = Repeater; + + trigger OnAction() + var + TestInputGroup: Record "Test Input Group"; + begin + CurrPage.SetSelectionFilter(TestInputGroup); + if TestInputGroup.IsEmpty() then + exit; + + if not Confirm(DeleteSelectedQst) then + exit; + + TestInputGroup.DeleteAll(true); + CurrPage.Update(false); + end; + } fileuploadaction(ImportDataInputs) { Caption = 'Import data-driven test inputs'; @@ -90,9 +112,15 @@ page 130462 "Test Input Groups" } area(Promoted) { + actionref(DeleteSelected_Promoted; DeleteSelected) + { + } actionref(ImportDefinition_Promoted; ImportDataInputs) { } } } + + var + DeleteSelectedQst: Label 'Are you sure you want to delete the selected test input groups?'; } \ No newline at end of file diff --git a/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInputsManagement.Codeunit.al b/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInputsManagement.Codeunit.al index 30f869a010..123707dd87 100644 --- a/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInputsManagement.Codeunit.al +++ b/src/Tools/Test Framework/Test Runner/src/DataDrivenTest/DataInputs/TestInputsManagement.Codeunit.al @@ -137,14 +137,20 @@ codeunit 130458 "Test Inputs Management" TestInputGroup: Record "Test Input Group"; TestInput: Record "Test Input"; InputText: Text; + SuiteSetupGroupName: Text; FileType: Text; TelemetryCD: Dictionary of [Text, Text]; begin - ReadMetadataFromFile(FileName, TestInputInStream, LanguageID, GroupName, InputText); + ReadMetadataFromFile(FileName, TestInputInStream, LanguageID, GroupName, SuiteSetupGroupName, InputText); if not TestInputGroup.Find() then CreateTestInputGroup(TestInputGroup, FileName, ImportedByAppId, LanguageID, GroupName); + if SuiteSetupGroupName <> '' then begin + TestInputGroup."Suite Setup Group Name" := CopyStr(SuiteSetupGroupName, 1, MaxStrLen(TestInputGroup."Suite Setup Group Name")); + TestInputGroup.Modify(true); + end; + if FileName.EndsWith(JsonFileExtensionTxt) then begin FileType := JsonFileExtensionTxt; TestInputInStream.Read(InputText); @@ -207,7 +213,7 @@ codeunit 130458 "Test Inputs Management" TestInputGroupCode := CopyStr(FileName, 1, MaxStrLen(TestInputGroupCode)); end; - local procedure ReadMetadataFromFile(FileName: Text; var TestInputInStream: InStream; var LanguageID: Integer; var GroupName: Text; var InputText: Text) + local procedure ReadMetadataFromFile(FileName: Text; var TestInputInStream: InStream; var LanguageID: Integer; var GroupName: Text; var SuiteSetupGroupName: Text; var InputText: Text) var WindowsLanguage: Record "Windows Language"; MetadataJsonObject: JsonObject; @@ -231,6 +237,10 @@ codeunit 130458 "Test Inputs Management" if MetadataJsonObject.Get(NameTok, MetadataJsonToken) then if MetadataJsonToken.IsValue() then GroupName := MetadataJsonToken.AsValue().AsText(); + + if MetadataJsonObject.Get(TestSuiteSetupTok, MetadataJsonToken) then + if MetadataJsonToken.IsValue() then + SuiteSetupGroupName := MetadataJsonToken.AsValue().AsText(); end; local procedure CreateTestInputGroup(var TestInputGroup: Record "Test Input Group"; FileName: Text; ImportedByAppId: Guid; LanguageID: Integer; GroupName: Text) @@ -294,6 +304,13 @@ codeunit 130458 "Test Inputs Management" if not DataInputJsonObject.ReadFromYaml(TestData) then Error(CouldNotParseYamlInputErr); + // Suite setup: store entire content as a single row (only when value is an object, not a scalar reference) + if DataInputJsonObject.Get(TestSuiteSetupTok, DataInputJsonToken) then + if not DataInputJsonToken.IsValue() then begin + InsertSuiteSetupDataInput(DataInputJsonToken, TestInputGroup); + exit; + end; + if not DataInputJsonObject.Get(TestsTok, DataInputJsonToken) then begin InsertDataInputLine(DataInputJsonObject, TestInputGroup); exit; @@ -305,7 +322,27 @@ codeunit 130458 "Test Inputs Management" exit; end; - InsertDataInputLine(DataInputJsonObject, TestInputGroup); + InsertDataInputLine(DataInputJsonToken.AsObject(), TestInputGroup); + end; + + local procedure InsertSuiteSetupDataInput(SuiteSetupJsonToken: JsonToken; var TestInputGroup: Record "Test Input Group") + var + TestInput: Record "Test Input"; + SuiteSetupText: Text; + begin + TestInput.SetRange("Test Input Group Code", TestInputGroup.Code); + if not TestInput.IsEmpty() then + Error(SuiteSetupOnlyOneRowErr); + + TestInput.Reset(); + TestInput."Test Input Group Code" := TestInputGroup.Code; + TestInput."Language ID" := TestInputGroup."Language ID"; + TestInput.Code := SuiteSetupInputCodeTok; + TestInput.Description := SuiteSetupInputCodeTok; + TestInput.Insert(true); + + SuiteSetupJsonToken.WriteTo(SuiteSetupText); + TestInput.SetInput(TestInput, SuiteSetupText); end; local procedure InsertDataInputsFromJsonArray(var TestInputGroup: Record "Test Input Group"; var DataOnlyTestInputsArray: JsonArray) @@ -405,12 +442,15 @@ codeunit 130458 "Test Inputs Management" LanguageTok: Label 'language', Locked = true; NameTok: Label 'name', Locked = true; TestsTok: Label 'tests', Locked = true; + TestSuiteSetupTok: Label 'suite_setup', Locked = true; TestInputTok: Label 'testInput', Locked = true; + SuiteSetupInputCodeTok: Label 'SUITE-SETUP', Locked = true; ChooseFileLbl: Label 'Choose a file to import'; TestInputNameTok: Label 'INPUT-', Locked = true; CouldNotParseYamlInputErr: Label 'The data does not represent valid YAML.'; CouldNotParseInputErr: Label 'Could not parse input dataset.'; CouldNotParseJsonlInputErr: Label 'Could not parse JSONL input line: %1', Comment = '%1 = JSON Line Content'; + SuiteSetupOnlyOneRowErr: Label 'Suite setup datasets can only contain a single entry per language.'; LineTypeMustBeCodeunitErr: Label 'Line type must be Codeunit.'; JsonFileExtensionTxt: Label '.json', Locked = true; JsonlFileExtensionTxt: Label '.jsonl', Locked = true;