From 243b9b4217c9320efa6f239c8a1e756eb047371c Mon Sep 17 00:00:00 2001 From: Michael Becker Date: Sun, 12 Oct 2025 13:14:41 -0400 Subject: [PATCH] preliminary implementation of Build UI Response Method and Build Element Method as MethodImplementations --- mocha-common | 2 +- .../src/lib/Mocha.Core/KnownInstanceGuids.cs | 6 +- .../lib/Mocha.Core/KnownRelationshipGuids.cs | 6 +- .../BuildElementMethodImplementation.cs | 165 ++++++++++++++++++ .../BuildUIResponseMethodImplementation.cs | 43 ++++- mocha-dotnet/src/lib/Mocha.Core/Oms.cs | 122 ++++++++----- .../src/lib/Mocha.Core/OmsMethodBuilder.cs | 18 +- .../src/lib/Mocha.Core/Oop/ElementContent.cs | 8 + .../Oop/Methods/BuildElementMethod.cs | 6 + .../MethodTests/BuildUIResponseMethodTests.cs | 113 ++++++++++++ 10 files changed, 435 insertions(+), 54 deletions(-) create mode 100644 mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/BuildElementMethodImplementation.cs create mode 100644 mocha-dotnet/src/lib/Mocha.Core/Oop/ElementContent.cs create mode 100644 mocha-dotnet/src/lib/Mocha.Core/Oop/Methods/BuildElementMethod.cs create mode 100644 mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/BuildUIResponseMethodTests.cs diff --git a/mocha-common b/mocha-common index 152eb33..6ee9931 160000 --- a/mocha-common +++ b/mocha-common @@ -1 +1 @@ -Subproject commit 152eb33273ba12ccad4f3a2e98c514617e11bcff +Subproject commit 6ee9931cff2ac2645df584f7d6d1c8f39e0fd768 diff --git a/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs b/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs index cec89b3..f96a4c2 100755 --- a/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs @@ -70,6 +70,7 @@ namespace Mocha.Core public static Guid SelectionFunction { get; } = new Guid("{bdaef55d-9905-4d24-84c2-7439d43a79df}"); // public static Guid MethodCall { get; } = new Guid("{084A6D58-32C9-4A5F-9D2B-86C46F74E522}"); + public static Guid BEMProcess { get; } = new Guid("{a4c5ffb4-bf37-49f3-9190-dc329d035b46}"); public static Guid ConditionGroup { get; } = new Guid("{df2059e6-650c-49a8-8188-570ccbe4fd2d}"); public static Guid ConditionalEvaluationCase { get; } = new Guid("{ba18abdc-11ae-46af-850a-eb30280b0ffa}"); @@ -249,7 +250,10 @@ namespace Mocha.Core public static Guid EvaluateBooleanExpressionMethod { get; } = new Guid("{e1529108-2f84-4a4c-89b3-a647bc3e41d7}"); // 24 // AR - Assign Relationship Method - 25 public static Guid GetReferencedInstanceSetMethod { get; } = new Guid("{bcfd0d64-3eba-4a97-9622-f3a960877d24}"); // 26 - // BEM - Build Element Method - 29 + /// + /// BEM - Build Element Method [1$29] + /// + public static Guid BuildElementMethod { get; } = new Guid("{c8f25550-0895-4e05-b4a0-f319a7ffcc4c}"); public static Guid BuildAttributeMethod { get; } = new Guid("{e5879955-0093-48c8-8042-813168578af2}"); // 30 /// /// CN - Calculate Numeric Method diff --git a/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs b/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs index 72f446e..36ec357 100755 --- a/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs @@ -147,6 +147,9 @@ namespace Mocha.Core public static Guid Build_Attribute_Method__builds_with__Build_Attribute_Method_Component { get; } = new Guid("{b4fad1b8-711c-4e84-82d0-e9a9e41e8aa7}"); public static Guid Build_Attribute_Method_Component__uses__Executable_returning_Attribute { get; } = new Guid("{9d2acd01-5c6d-4a95-b77e-5261ba109540}"); + public static Guid Build_Element_Method__has__BEM_Process { get; } = new Guid("{6f1811b0-4e58-4e66-8318-083b62aac5de}"); + public static Guid Build_Element_Method__returns__Element { get; } = new Guid("{4d13d021-7363-4131-b74a-241698c3f1d0}"); + public static Guid Get_Attribute_Method__returns__Attribute { get; } = new Guid("{5eca9b3f-be75-4f6e-8495-781480774833}"); public static Guid Attribute__returned_by__Get_Attribute_Method { get; } = new Guid("{e82ace2e-84b7-4912-89ed-7b8efd63bb5d}"); @@ -440,7 +443,8 @@ namespace Mocha.Core public static Guid PUM_Process__invokes__Execute_Update_Method_Binding { get; } = new Guid("{d3e83c17-fd38-46a0-a055-66281eabe9b0}"); public static Guid BEM_Process__uses_loop__Executable_returning_Instance_Set { get; } = new Guid("{0fb2b538-eacb-418a-b7d8-43a584b85952}"); - + public static Guid BEM_Process__uses_order__Executable_returning_Attribute { get; } = new Guid("{0e1e6e71-e0ee-4b94-a912-ba1c6bebed2b}"); + public static Guid Get_Instances_Method__returns__Work_Set { get; } = new Guid("{7d0f93b1-8c93-464e-a44d-d674f910b589}"); public static Guid Get_Instances_Method__selects_instances_of__Class { get; } = new Guid("{c0b85d90-de8c-44c2-9420-c5e724ccdf2c}"); public static Guid Method_Binding__uses_super__Return_Instance_Set_Method_Binding { get; } = new Guid("{444279f1-3bf9-4d1f-848e-e7bf33fa0fd7}"); diff --git a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/BuildElementMethodImplementation.cs b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/BuildElementMethodImplementation.cs new file mode 100644 index 0000000..97cc6c1 --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/BuildElementMethodImplementation.cs @@ -0,0 +1,165 @@ + +using System.Text.Json.Nodes; +using System.Threading.Tasks.Dataflow; +using Mocha.Core.Oop; +using Mocha.Core.UI; + +namespace Mocha.Core.MethodImplementations; + +public class BuildElementMethodImplementation : MethodImplementation +{ + + public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.BuildElementMethod; + + protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) + { + InstanceHandle element = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Build_Element_Method__returns__Element)); + InstanceHandle layout = oms.GetRelatedInstance(element, oms.GetInstance(KnownRelationshipGuids.Element__has__Layout)); + + if (oms.IsInstanceOf(layout, oms.GetInstance(KnownInstanceGuids.Classes.GroupLayout))) + { + + } + + InstanceHandle bemProcess = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Build_Element_Method__has__BEM_Process)); + + InstanceHandle loopInstanceSet = oms.GetRelatedInstance(bemProcess, oms.GetInstance(KnownRelationshipGuids.BEM_Process__uses_loop__Executable_returning_Instance_Set)); + object? instanceSet = oms.Evaluate(context, loopInstanceSet, InstanceHandle.Empty); + if (instanceSet is IEnumerable ihs) + { + JsonObject obj = BuildGrid(oms, element, ihs); + context.SetWorkData(element, obj); + } + + return element; + } + + private JsonObject BuildGrid(Oms oms, InstanceHandle element, IEnumerable instances) + { + IEnumerable ihCols = oms.GetRelatedInstances(element, oms.GetInstance(KnownRelationshipGuids.Element__has__Element_Content)); + JsonObject obj = new JsonObject(); + obj.Add("widget", "grid"); + obj.Add("iid", oms.GetInstanceKey(element).ToString()); + obj.Add("enabled", false); + + int j = 1; + JsonArray aryCols = new JsonArray(); + foreach (InstanceHandle ihCol in ihCols) + { + JsonObject objCol = BuildGridColumn(oms, ihCol, j); + aryCols.Add(objCol); + j++; + } + obj.Add("columns", aryCols); + + JsonArray aryRows = new JsonArray(); + int i = 1; + foreach (InstanceHandle ih in instances) + { + JsonObject objRow = new JsonObject(); + objRow.Add("widget", "row"); + objRow.Add("iid", oms.GetInstanceKey(element).ToString()); + objRow.Add("enabled", false); + objRow.Add("rowIndex", i); + + JsonObject objCells = new JsonObject(); + j = 1; + foreach (InstanceHandle ihCol in ihCols) + { + JsonObject objCell = BuildGridCell(oms, ih, ihCol); + objCells.Add("46." + j.ToString(), objCell); + j++; + } + + objRow.Add("cellsMap", objCells); + aryRows.Add(objRow); + + i++; + } + obj.Add("rows", aryRows); + return obj; + } + + private JsonObject BuildGridColumn(Oms oms, InstanceHandle elementContent, int index) + { + JsonObject objCol = new JsonObject(); + objCol.Add("widget", "column"); + objCol.Add("ecid", oms.GetInstanceKey(elementContent).ToString()); + + InstanceHandle elementContentInstance = oms.GetRelatedInstance(elementContent, oms.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance)); + if (elementContentInstance != InstanceHandle.Empty) + { + objCol.Add("iid", oms.GetInstanceKey(elementContentInstance).ToString()); + } + objCol.Add("enabled", false); + objCol.Add("label", oms.GetLabelForUIElement(elementContent)); + + JsonObject objCellShell = new JsonObject(); + objCellShell.Add("widget", "monikerList"); + objCol.Add("cellShell", objCellShell); + + objCol.Add("columnId", "46." + index.ToString()); + objCol.Add("sortableAndFilterable", true); + // objCol.Add("propertyName", ""); + return objCol; + } + + private JsonObject BuildGridCell(Oms oms, InstanceHandle targetInstance, InstanceHandle elementContent) + { + JsonObject objCell = new JsonObject(); + objCell.Add("ecid", oms.GetInstanceKey(elementContent).ToString()); + + InstanceHandle ecInst = oms.GetRelatedInstance(elementContent, oms.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance)); + objCell.Add("iid", oms.GetInstanceKey(ecInst).ToString()); + + objCell.Add("label", oms.GetLabelForUIElement(elementContent)); + //objCell.Add("propertyName", ""); + + InstanceHandle do_NotEnterable = oms.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.NotEnterable); + + IEnumerable displayOptions = oms.GetRelatedInstances(elementContent, oms.GetInstance(KnownRelationshipGuids.Element_Content__has__Element_Content_Display_Option)); + if (displayOptions.Contains(do_NotEnterable)) + { + objCell.Add("enabled", false); + } + // objCell.Add("helpText", "blah blah"); + + if (oms.IsInstanceOf(ecInst, oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute))) + { + objCell.Add("widget", "text"); + objCell.Add("value", oms.GetAttributeValue(targetInstance, ecInst)); + } + else if (oms.IsInstanceOf(ecInst, oms.GetInstance(KnownInstanceGuids.Classes.BooleanAttribute))) + { + objCell.Add("widget", "checkBox"); + objCell.Add("value", oms.GetAttributeValue(targetInstance, ecInst)); + objCell.Add("text", oms.GetAttributeValue(targetInstance, ecInst) ? "Yes" : "No"); + } + else if (oms.IsInstanceOf(ecInst, oms.GetInstance(KnownInstanceGuids.Classes.NumericAttribute))) + { + objCell.Add("widget", "number"); + objCell.Add("value", oms.GetAttributeValue(targetInstance, ecInst)); + objCell.Add("text", oms.GetAttributeValue(targetInstance, ecInst).ToString()); + objCell.Add("precision", 6); + objCell.Add("format", "#0.######"); + } + else if (oms.IsInstanceOf(ecInst, oms.GetInstance(KnownInstanceGuids.Classes.DateAttribute))) + { + objCell.Add("widget", "date"); + + DateTime dt = oms.GetAttributeValue(targetInstance, ecInst); + JsonObject objDate = new JsonObject(); + objDate.Add("Y", dt.Year.ToString()); + objDate.Add("M", dt.Month.ToString().PadLeft(2, '0')); + objDate.Add("D", dt.Day.ToString().PadLeft(2, '0')); + objCell.Add("value", objDate); + objCell.Add("text", dt.ToString()); + objCell.Add("dateTimePrecision", "DAY"); + } + else + { + objCell.Add("widget", "monikerList"); + } + return objCell; + } +} \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/BuildUIResponseMethodImplementation.cs b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/BuildUIResponseMethodImplementation.cs index e993bc7..4877ba6 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/BuildUIResponseMethodImplementation.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/BuildUIResponseMethodImplementation.cs @@ -15,6 +15,8 @@ // You should have received a copy of the GNU General Public License // along with Mocha.NET. If not, see . +using System.Text.Json.Nodes; + namespace Mocha.Core.MethodImplementations; public class BuildUIResponseMethodImplementation : MethodImplementation @@ -30,6 +32,45 @@ public class BuildUIResponseMethodImplementation : MethodImplementation throw new InvalidOperationException("no return Element specified for method"); } - return returnsElement; + InstanceHandle element = oms.Execute(context, returnsElement); + object? data = context.GetWorkData(element); + if (data is JsonObject objChild) + { + JsonObject objRoot = new JsonObject(); + objRoot.Add("widget", "root"); + objRoot.Add("body", objChild); + + JsonObject objTitle = new JsonObject(); + // task like 2501$6 (View Organization) has EC which has display option `Display as Page Title`, in which + // the title widget is a titleMonikerList with the sole instance being the organization currently being viewed + objTitle.Add("widget", "titleMonikerList"); + objTitle.Add("label", "Page Title"); // this is the title as displayed in the Web browser title bar + objTitle.Add("text", "Page Title"); // same as 'label' + + InstanceHandle inst = oms.GetInstance(KnownAttributeGuids.Text.Token); + + JsonArray ary = new JsonArray(); + JsonObject obj = CreateMoniker(oms, inst); + ary.Add(obj); + objTitle.Add("instances", ary); + + objRoot.Add("title", objTitle); + context.SetWorkData(element, objRoot); + } + + return element; } + + private JsonObject CreateMoniker(Oms oms, InstanceHandle inst) + { + JsonObject obj = new JsonObject(); + obj.Add("widget", "moniker"); + obj.Add("instanceId", oms.GetInstanceKey(inst).ToString()); + obj.Add("text", oms.GetInstanceText(inst)); + obj.Add("rt", true); // whether Related Tasks should be shown + obj.Add("pv", true); // whether Preview should be enabled + obj.Add("v", true); // ??? + obj.Add("uxiTags", "ml-feedback-id="); // ???, something new + return obj; + } } \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs index 2cde6da..48c9b8c 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs @@ -2175,6 +2175,10 @@ public abstract class Oms } } + public string GetLabelForUIElement(ElementContent parentElementContent) + { + return GetLabelForUIElement(parentElementContent.GetHandle()); + } public string GetLabelForUIElement(InstanceHandle parentElementContent) { InstanceHandle parentInstance = GetRelatedInstance(parentElementContent, GetInstance(KnownRelationshipGuids.Element_Content__has__Instance)); @@ -2594,64 +2598,88 @@ public abstract class Oms throw new FormatException(); } - public object? Evaluate(OmsContext context, InstanceHandle workDataInstance, InstanceHandle sourceInstance, object? defaultValue = null) + public object? Evaluate(OmsContext context, object? workDataObject, InstanceHandle sourceInstance, object? defaultValue = null) { object? value = defaultValue; - if (IsInstanceOf(workDataInstance, GetInstance(KnownInstanceGuids.Classes.TextAttribute))) + if (workDataObject is InstanceHandle workDataInstance) { - if (sourceInstance != InstanceHandle.Empty) + if (IsInstanceOf(workDataInstance, GetInstance(KnownInstanceGuids.Classes.TextAttribute))) { - // first check our target instance for the attribute. this MAY be empty - value = GetAttributeValue(sourceInstance, workDataInstance); + if (sourceInstance != InstanceHandle.Empty) + { + // first check our target instance for the attribute. this MAY be empty + value = GetAttributeValue(sourceInstance, workDataInstance); + } + else + { + value = context.GetWorkData(workDataInstance); + } + } + else if (IsInstanceOf(workDataInstance, GetInstance(KnownInstanceGuids.Classes.BooleanAttribute))) + { + if (sourceInstance != InstanceHandle.Empty) + { + // first check our target instance for the attribute. this MAY be empty + value = GetAttributeValue(sourceInstance, workDataInstance); + } + else + { + value = context.GetWorkData(workDataInstance); + } + } + else if (IsInstanceOf(workDataInstance, GetInstance(KnownInstanceGuids.Classes.NumericAttribute))) + { + if (sourceInstance != InstanceHandle.Empty) + { + // first check our target instance for the attribute. this MAY be empty + value = GetAttributeValue(sourceInstance, workDataInstance); + } + else + { + value = context.GetWorkData(workDataInstance); + } + } + else if (IsInstanceOf(workDataInstance, GetInstance(KnownInstanceGuids.Classes.DateAttribute))) + { + if (sourceInstance != InstanceHandle.Empty) + { + // first check our target instance for the attribute. this MAY be empty + value = GetAttributeValue(sourceInstance, workDataInstance); + } + else + { + value = context.GetWorkData(workDataInstance); + } + } + else if (IsInstanceOf(workDataInstance, GetInstance(KnownInstanceGuids.Classes.WorkSet))) + { + if (sourceInstance != InstanceHandle.Empty) + { + // first check our target instance for the attribute. this MAY be empty + // value = GetAttributeValue(sourceInstance, workDataInstance); + } + else + { + value = context.GetWorkData(workDataInstance); + } + } + else if (IsInstanceOf(workDataInstance, GetInstance(KnownInstanceGuids.Classes.Executable))) + { + InstanceHandle workSet = Execute(context, workDataInstance); + value = context.GetWorkData(workSet); } else { - value = context.GetWorkData(workDataInstance); - } - } - else if (IsInstanceOf(workDataInstance, GetInstance(KnownInstanceGuids.Classes.BooleanAttribute))) - { - if (sourceInstance != InstanceHandle.Empty) - { - // first check our target instance for the attribute. this MAY be empty - value = GetAttributeValue(sourceInstance, workDataInstance); - } - else - { - value = context.GetWorkData(workDataInstance); - } - } - else if (IsInstanceOf(workDataInstance, GetInstance(KnownInstanceGuids.Classes.NumericAttribute))) - { - if (sourceInstance != InstanceHandle.Empty) - { - // first check our target instance for the attribute. this MAY be empty - value = GetAttributeValue(sourceInstance, workDataInstance); - } - else - { - value = context.GetWorkData(workDataInstance); - } - } - else if (IsInstanceOf(workDataInstance, GetInstance(KnownInstanceGuids.Classes.DateAttribute))) - { - if (sourceInstance != InstanceHandle.Empty) - { - // first check our target instance for the attribute. this MAY be empty - value = GetAttributeValue(sourceInstance, workDataInstance); - } - else - { - value = context.GetWorkData(workDataInstance); + context.SetWorkData(GetInstance(KnownInstanceGuids.WorkSets.TaskRelatedInstance), context.InitiatingInstance); + + InstanceHandle workData = Execute(context, workDataInstance); + object? val = context.GetWorkData(workData); + value = val?.ToString(); } } else { - context.SetWorkData(GetInstance(KnownInstanceGuids.WorkSets.TaskRelatedInstance), context.InitiatingInstance); - - InstanceHandle workData = Execute(context, workDataInstance); - object? val = context.GetWorkData(workData); - value = val?.ToString(); + value = workDataObject; } return value; } diff --git a/mocha-dotnet/src/lib/Mocha.Core/OmsMethodBuilder.cs b/mocha-dotnet/src/lib/Mocha.Core/OmsMethodBuilder.cs index 6ad97c5..01a0b31 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/OmsMethodBuilder.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/OmsMethodBuilder.cs @@ -348,8 +348,20 @@ public class OmsMethodBuilder return new CalculateDateMethod(method); } - public BuildUIResponseMethod CreateBuildUIResponseMethod(InstanceHandle forClassInstance, string verb, string name, AccessModifier accessModifier, bool isStatic, InstanceHandle usesExecutableReturningElement) - { + public BuildElementMethod CreateBuildElementMethod(InstanceHandle forClassInstance, string verb, string name, AccessModifier accessModifier, bool isStatic, InstanceHandle hasBemProcess, InstanceHandle returnsElement) + { + InstanceHandle method = CreateMethodBase(Oms.GetInstance(KnownInstanceGuids.MethodClasses.BuildElementMethod), forClassInstance, verb, name, accessModifier, isStatic); + Oms.AssignRelationship(method, Oms.GetInstance(KnownRelationshipGuids.Build_Element_Method__has__BEM_Process), hasBemProcess); + Oms.AssignRelationship(method, Oms.GetInstance(KnownRelationshipGuids.Build_Element_Method__returns__Element), returnsElement); + return new BuildElementMethod(method); + } + + public BuildUIResponseMethod CreateBuildUIResponseMethod(InstanceHandle forClassInstance, string verb, string name, AccessModifier accessModifier, bool isStatic, IExecutableReturningElement usesExecutableReturningElement) + { + return CreateBuildUIResponseMethod(forClassInstance, verb, name, accessModifier, isStatic, usesExecutableReturningElement.GetHandle()); + } + public BuildUIResponseMethod CreateBuildUIResponseMethod(InstanceHandle forClassInstance, string verb, string name, AccessModifier accessModifier, bool isStatic, InstanceHandle usesExecutableReturningElement) + { InstanceHandle method = CreateMethodBase(Oms.GetInstance(KnownInstanceGuids.MethodClasses.BuildUIResponseMethod), forClassInstance, verb, name, accessModifier, isStatic); InstanceHandle r_Build_UI_Response_Method__uses__Executable_returning_Element = Oms.GetInstance(KnownRelationshipGuids.Build_UI_Response_Method__uses__Executable_returning_Element); if (usesExecutableReturningElement != InstanceHandle.Empty) @@ -361,7 +373,7 @@ public class OmsMethodBuilder //? should we throw an exception here? } return new BuildUIResponseMethod(method); - } + } public ControlTransactionMethod CreateControlTransactionMethod(InstanceHandle forClassInstance, string verb, string name, AccessModifier accessModifier, bool isStatic, InstanceHandle processesElement, BuildResponseMethodBinding usesBuildResponseMethodBinding) { diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oop/ElementContent.cs b/mocha-dotnet/src/lib/Mocha.Core/Oop/ElementContent.cs new file mode 100644 index 0000000..76387da --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Core/Oop/ElementContent.cs @@ -0,0 +1,8 @@ +namespace Mocha.Core.Oop; + +public class ElementContent : ConcreteInstanceWrapper +{ + public ElementContent(InstanceHandle handle) : base(handle) + { + } +} \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oop/Methods/BuildElementMethod.cs b/mocha-dotnet/src/lib/Mocha.Core/Oop/Methods/BuildElementMethod.cs new file mode 100644 index 0000000..ac3513a --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Core/Oop/Methods/BuildElementMethod.cs @@ -0,0 +1,6 @@ +namespace Mocha.Core.Oop.Methods; + +public class BuildElementMethod : MethodReturningElement +{ + public BuildElementMethod(InstanceHandle handle) : base(handle) { } +} \ No newline at end of file diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/BuildUIResponseMethodTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/BuildUIResponseMethodTests.cs new file mode 100644 index 0000000..e78d22e --- /dev/null +++ b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/BuildUIResponseMethodTests.cs @@ -0,0 +1,113 @@ +// Copyright (C) 2024 Michael Becker +// +// This file is part of Mocha.NET. +// +// Mocha.NET is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Mocha.NET 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Mocha.NET. If not, see . + +using System.Text.Json.Nodes; +using Mocha.Core.Oop; +using Mocha.Core.Oop.Methods; + +namespace Mocha.Core.Tests.MethodTests; + +public class BuildUIResponseMethodTests : MethodTestsBase +{ + + [Test] + public void Test1() + { + InstanceHandle irTestClass = Oms.GetInstance(TEST_CLASS_GUID); + Assert.That(irTestClass, Is.Not.EqualTo(InstanceHandle.Empty)); + + InstanceHandle a_Name = Oms.GetInstance(KnownAttributeGuids.Text.Name); + InstanceHandle a_Index = Oms.GetInstance(KnownAttributeGuids.Numeric.Index); + InstanceHandle a_Static = Oms.GetInstance(KnownAttributeGuids.Boolean.Static); + Oms.AddAttribute(irTestClass, a_Name); + Oms.AddAttribute(irTestClass, a_Index); + Oms.AddAttribute(irTestClass, a_Static); + + InstanceHandle i_TestClass1 = Oms.CreateInstanceOf(irTestClass); + InstanceHandle i_TestClass2 = Oms.CreateInstanceOf(irTestClass); + + OmsMethodBuilder methodBuilder = new OmsMethodBuilder(Oms); + WorkSet ws = Oms.CreateWorkSet("test"); + + Oms.SetAttributeValue(i_TestClass1, a_Name, "Test Class Instance 1"); + Oms.SetAttributeValue(i_TestClass2, a_Name, "Another Test Instance"); + + Oms.SetAttributeValue(i_TestClass1, a_Index, 42M); + Oms.SetAttributeValue(i_TestClass2, a_Index, 36M); + + Oms.SetAttributeValue(i_TestClass1, a_Static, true); + Oms.SetAttributeValue(i_TestClass2, a_Static, false); + + Method gsi = methodBuilder.CreateGetSpecifiedInstancesMethod(irTestClass, "get", "Test Class Instances", ws, new InstanceHandle[] + { + i_TestClass1, + i_TestClass2 + }); + + MethodReturningAttribute gaOrder = methodBuilder.CreateGetAttributeMethod(irTestClass, "get", "Order", Oms.GetInstance(KnownAttributeGuids.Text.Order)); + ReturnAttributeMethodBinding rambOrder = gaOrder.CreateMethodBinding(Oms); + + InstanceHandle bemProcess = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.BEMProcess)); + + // loop on the GSI defined above + Oms.AssignRelationship(bemProcess, Oms.GetInstance(KnownRelationshipGuids.BEM_Process__uses_loop__Executable_returning_Instance_Set), gsi.GetHandle()); + + // Oms.AssignRelationship(bemProcess, Oms.GetInstance(KnownRelationshipGuids.BEM_Process__uses_build__Executable_returning_Work_Data), huh); + Oms.AssignRelationship(bemProcess, Oms.GetInstance(KnownRelationshipGuids.BEM_Process__uses_order__Executable_returning_Attribute), rambOrder); + + InstanceHandle elem = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.Element)); + InstanceHandle layout = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.GroupLayout)); + Oms.AssignRelationship(elem, Oms.GetInstance(KnownRelationshipGuids.Element__has__Layout), layout); + + InstanceHandle ecName = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.ElementContent)); + Oms.AssignRelationship(ecName, Oms.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance), a_Name); + + InstanceHandle ecIndex = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.ElementContent)); + Oms.AssignRelationship(ecIndex, Oms.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance), a_Index); + + InstanceHandle ecEditable = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.ElementContent)); + Oms.AssignRelationship(ecEditable, Oms.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance), a_Static); + + Oms.AssignRelationship(elem, Oms.GetInstance(KnownRelationshipGuids.Element__has__Element_Content), new InstanceHandle[] + { + ecName, + ecIndex, + ecEditable + }); + + MethodReturningElement bem = methodBuilder.CreateBuildElementMethod(irTestClass, "build", "element", AccessModifier.Public, true, bemProcess, elem); + ReturnElementMethodBinding remb = bem.CreateMethodBinding(Oms); + + Method buir = methodBuilder.CreateBuildUIResponseMethod(irTestClass, "build", "response", AccessModifier.Public, true, remb); + + OmsContext context = Oms.CreateContext(); + + InstanceHandle wsH = Oms.Execute(context, buir); + object? workData = context.GetWorkData(wsH); + + Assert.That(workData, Is.InstanceOf()); + + JsonObject o = (JsonObject)workData; + + string s = o.ToJsonString(); + Assert.That(o["widget"]?.GetValue(), Is.EqualTo("root")); + Assert.That(o["body"]["rows"][0]["cellsMap"].AsObject().Count, Is.EqualTo(3)); + Assert.That(o["body"]["rows"][0]["cellsMap"]["46.1"]["label"].GetValue(), Is.EqualTo("Name")); + Assert.That(o["body"]["rows"][0]["cellsMap"]["46.1"]["value"].GetValue(), Is.EqualTo("Test Class Instance 1")); + } + +} \ No newline at end of file