diff --git a/mocha-common b/mocha-common index 5b9701d..152eb33 160000 --- a/mocha-common +++ b/mocha-common @@ -1 +1 @@ -Subproject commit 5b9701dcc1b935c5467fdec26b80846877616db6 +Subproject commit 152eb33273ba12ccad4f3a2e98c514617e11bcff diff --git a/mocha-dotnet/src/lib/Mocha.Core/InstanceKey.cs b/mocha-dotnet/src/lib/Mocha.Core/InstanceKey.cs index 95052ec..8810a30 100755 --- a/mocha-dotnet/src/lib/Mocha.Core/InstanceKey.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/InstanceKey.cs @@ -34,14 +34,12 @@ namespace Mocha.Core public bool IsDerived { get { return _derivedDataString != null; } } internal Oms? _oms; - internal InstanceHandle _inst; internal InstanceHandle _parentClassInstance; private string? _derivedDataString = null; - internal void SetDerivedData(Oms oms, InstanceHandle inst, Dictionary derivedData) + internal void SetDerivedData(Oms oms, InstanceHandle parentClassInstance, Dictionary derivedData) { _oms = oms; - _inst = inst; - _parentClassInstance = oms.GetParentClass(inst); + _parentClassInstance = parentClassInstance; Dictionary _derivedData = new Dictionary(); foreach (KeyValuePair kvp in derivedData) @@ -131,6 +129,15 @@ namespace Mocha.Core _isNotEmpty = true; } + public static InstanceKey CreateDerivedInstanceKey(Oms oms, InstanceHandle parentClassInstance, Dictionary derivedData) + { + InstanceKey ikParent = oms.GetInstanceKey(parentClassInstance); + InstanceKey ik = new InstanceKey(ikParent.InstanceIndex, 0); + + ik.SetDerivedData(oms, parentClassInstance, derivedData); + return ik; + } + public override bool Equals(object obj) { return (obj is InstanceKey) && ((InstanceKey)obj).ClassIndex == ClassIndex && ((InstanceKey)obj).InstanceIndex == InstanceIndex && ((InstanceKey)obj).IsEmpty == IsEmpty && ((InstanceKey)obj).IsDerived == IsDerived; @@ -176,12 +183,16 @@ namespace Mocha.Core return b64; } - internal Dictionary? GetDerivedData() + internal Dictionary? GetDerivedData(Oms? oms = null) { Dictionary derivedData = new Dictionary(); + if (oms == null) + { + oms = _oms; + } InstanceKey ikParentClass = new InstanceKey(1, ClassIndex); - _parentClassInstance = _oms.GetInstance(ikParentClass); + _parentClassInstance = oms.GetInstance(ikParentClass); if (_derivedDataString != null) { @@ -189,10 +200,10 @@ namespace Mocha.Core MemoryStream ms = new MemoryStream(data); BinaryReader br = new BinaryReader(ms); - IEnumerable attributes = _oms.GetRelatedInstances(_parentClassInstance, _oms.GetInstance(KnownRelationshipGuids.Class__has__Attribute)); + IEnumerable attributes = oms.GetRelatedInstances(_parentClassInstance, oms.GetInstance(KnownRelationshipGuids.Class__has__Attribute)); foreach (InstanceHandle att in attributes) { - if (_oms.IsInstanceOf(att, _oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute))) + if (oms.IsInstanceOf(att, oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute))) { if (br.BaseStream.EndOfStream()) { diff --git a/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs b/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs index 40a8797..ffedeeb 100755 --- a/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/KnownInstanceGuids.cs @@ -226,6 +226,13 @@ namespace Mocha.Core } } + [ExportEntities(Prefix = "IDC_", Suffix = null)] + public static class InstanceOpClasses + { + public static Guid BuildDynamicInstanceOp { get; } = new Guid("{622edf0d-5e3d-49fd-9764-33aa304addf4}"); + public static Guid FilterByTypeOp { get; } = new Guid("{8344a933-bb49-4d1c-b92a-a044fc9b9611}"); + } + [ExportEntities(Prefix = "IDC_", Suffix = null)] public static class MethodClasses { @@ -524,6 +531,7 @@ namespace Mocha.Core public static Guid AccessModifierNonsingular { get; } = new Guid("{686a3322-03a5-4da6-ab00-33548cc03b98}"); public static Guid ParentClass { get; } = new Guid("{98da8ac1-1fea-4cb4-a278-0c5460e625fd}"); public static Guid DestinationClassForRelationship { get; } = new Guid("{cc6bf015-ea36-4cc5-8855-5047095affee}"); + public static Guid Set { get; } = new Guid("{40565aa8-892b-4a36-9a8e-54d55d1c6efe}"); } } } diff --git a/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs b/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs index cf23e4d..feef2c3 100755 --- a/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs @@ -123,8 +123,8 @@ namespace Mocha.Core public static Guid Instance_Set__has__Instance { get; } = new Guid("{7c9010a2-69f1-4029-99c8-72e05c78c41e}"); - public static Guid Parameter_Assignment__assigns_to__Parameter { get; } = new Guid("{a6d30e78-7bff-4fcc-b109-ee96681b0a9e}"); - public static Guid Parameter__assigned_from__Parameter_Assignment { get; } = new Guid("{2085341e-5e7e-4a7f-bb8d-dfa58f6030d9}"); + // public static Guid Parameter_Assignment__assigns_to__Parameter { get; } = new Guid("{a6d30e78-7bff-4fcc-b109-ee96681b0a9e}"); + // public static Guid Parameter__assigned_from__Parameter_Assignment { get; } = new Guid("{2085341e-5e7e-4a7f-bb8d-dfa58f6030d9}"); public static Guid Executable_returning_Work_Data__assigned_from__Parameter_Assignment { get; } = new Guid("{40540642-69b3-4713-ac55-6946060bd385}"); public static Guid Parameter_Assignment__assigns_from__Executable_returning_Work_Data { get; } = new Guid("{6f3687ed-7d88-4ece-914e-c47c57c1146d}"); @@ -454,5 +454,13 @@ namespace Mocha.Core public static Guid Arithmetic_Calculation__has_first_operand__Calculation { get; } = new Guid("{4f002495-dee4-4eca-8a15-beb8f928648d}"); public static Guid Arithmetic_Calculation__has_second_operand__Calculation { get; } = new Guid("{0d74918d-5e7b-4492-9fa4-e35558f40ef3}"); + + public static Guid Op_Scope__invokes__Instance_Op { get; } = new Guid("{eb78eaca-dbb1-4137-9a2d-b003c83ecb16}"); + public static Guid Instance_Op_Method__returns__Work_Set { get; } = new Guid("{aadc223e-e300-4914-ad29-62d497afcc36}"); + + public static Guid Build_Dynamic_Instance_Op__builds_dynamic__Class { get; } = new Guid("{e43ace17-110c-494f-8c68-4302785da3ca}"); + public static Guid Build_Dynamic_Instance_Op__assigns_instance_data_from__Parameter_Assignment { get; } = new Guid("{f5b1f747-fae3-4318-958b-a64f7cdd8b42}"); + + public static Guid Filter_By_Type_Op__uses__Class { get; } = new Guid("{2f5fddc8-5ab0-4c59-8a83-536a2ce0a30c}"); } } diff --git a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/InstanceOpMethodImplementation.cs b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/InstanceOpMethodImplementation.cs new file mode 100644 index 0000000..f4307db --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/InstanceOpMethodImplementation.cs @@ -0,0 +1,74 @@ +// 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 . + +namespace Mocha.Core.MethodImplementations; + +public class InstanceOpMethodImplementation : MethodImplementation +{ + public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.InstanceOpMethod; + protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) + { + InstanceHandle op = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Op_Scope__invokes__Instance_Op)); + if (op == InstanceHandle.Empty) + { + throw new InvalidOperationException("Instance Op Method does not invoke an Instance Op"); + } + + InstanceHandle workSet = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Instance_Op_Method__returns__Work_Set)); + + if (oms.IsInstanceOf(op, oms.GetInstance(KnownInstanceGuids.InstanceOpClasses.BuildDynamicInstanceOp))) + { + InstanceHandle buildsInstanceOf = oms.GetRelatedInstance(op, oms.GetInstance(KnownRelationshipGuids.Build_Dynamic_Instance_Op__builds_dynamic__Class)); + IEnumerable parmAssigns = oms.GetRelatedInstances(op, oms.GetInstance(KnownRelationshipGuids.Build_Dynamic_Instance_Op__assigns_instance_data_from__Parameter_Assignment)); + Dictionary data = new Dictionary(); + + foreach (InstanceHandle parmAssign in parmAssigns) + { + InstanceHandle assignsFromWorkData = oms.GetRelatedInstance(parmAssign, oms.GetInstance(KnownRelationshipGuids.Parameter_Assignment__assigns_from__Executable_returning_Work_Data)); + InstanceHandle assignsToWorkData = oms.GetRelatedInstance(parmAssign, oms.GetInstance(KnownRelationshipGuids.Parameter_Assignment__assigns_to__Work_Data)); + + data[assignsToWorkData] = oms.Evaluate(context, assignsFromWorkData, InstanceHandle.Empty); + } + + InstanceKey ik = InstanceKey.CreateDerivedInstanceKey(oms, buildsInstanceOf, data); + + InstanceHandle ih = oms.GetInstance(ik); + context.SetWorkData(workSet, ih); + } + else if (oms.IsInstanceOf(op, oms.GetInstance(KnownInstanceGuids.InstanceOpClasses.FilterByTypeOp))) + { + List list = new List(); + + InstanceHandle parentClass = oms.GetRelatedInstance(op, oms.GetInstance(KnownRelationshipGuids.Filter_By_Type_Op__uses__Class)); + + object? oSet = context.GetWorkData(oms.GetInstance(KnownInstanceGuids.WorkSets.Set)); + if (oSet is IEnumerable set) + { + foreach (InstanceHandle ih in set) + { + if (oms.IsInstanceOf(ih, parentClass)) + { + list.Add(ih); + } + } + } + + context.SetWorkData(workSet, list); + } + return workSet; + } +} diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs index 82035f3..2cde6da 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs @@ -313,13 +313,19 @@ public abstract class Oms { return new InstanceKey(1, 1); } + if (_derivedInstanceKeys.ContainsKey(instance)) + { + InstanceKey ik = InstanceKey.Parse(_derivedInstanceKeys[instance]); + ik._oms = this; + return ik; + } if (IsDerivedInstance(instance.GetHandle())) { InstanceHandle parent = GetParentClass(instance); InstanceKey ikParent = GetInstanceKeyInternal(parent); InstanceKey ik = new InstanceKey(ikParent.InstanceIndex, -1); - ik.SetDerivedData(this, instance.GetHandle(), GetDerivedData(instance.GetHandle())); + ik.SetDerivedData(this, parent, GetDerivedData(instance.GetHandle())); return ik; } return GetInstanceKeyInternal(instance.GetHandle()); @@ -405,20 +411,24 @@ public abstract class Oms { InstanceHandle ihSourceClass = GetRelatedInstance(relationship, GetInstance(KnownRelationshipGuids.Relationship__has_source__Class)); InstanceHandle ihDestinationClass = GetRelatedInstance(relationship, GetInstance(KnownRelationshipGuids.Relationship__has_destination__Class)); - List ignoreClasses = new List(); - if (TryGetInstance(KnownInstanceGuids.Classes.Instance, out InstanceHandle __ih_1)) - { - ignoreClasses.Add(__ih_1); - } - if (TryGetInstance(KnownInstanceGuids.Classes.ExecutableReturningWorkData, out InstanceHandle __ih_2)) - { - ignoreClasses.Add(__ih_2); - } - if (TryGetInstance(KnownInstanceGuids.Classes.Calculation, out InstanceHandle __ih_3)) - { - ignoreClasses.Add(__ih_3); - } + Guid[] ignoreClassGuids = new Guid[] + { + KnownInstanceGuids.Classes.Instance, + KnownInstanceGuids.Classes.ExecutableReturningWorkData, + KnownInstanceGuids.Classes.Calculation, + KnownInstanceGuids.Classes.WorkData + }; + + List ignoreClasses = new List(); + foreach (Guid ignoreClassGuid in ignoreClassGuids) + { + if (TryGetInstance(ignoreClassGuid, out InstanceHandle __ih)) + { + ignoreClasses.Add(__ih); + } + } + if (ihSourceClass != InstanceHandle.Empty) { if (!IsInstanceOf(source, ihSourceClass) && !ignoreClasses.Contains(ihSourceClass)) @@ -506,6 +516,7 @@ public abstract class Oms } private Dictionary _derivedInstances = new Dictionary(); + private Dictionary _derivedInstanceKeys = new Dictionary(); public InstanceHandle GetInstance(InstanceKey ik) { if (ik.IsDerived) @@ -518,9 +529,9 @@ public abstract class Oms inst = InstanceHandle.Create(); _derivedInstances[ik.ToString()] = inst; + _derivedInstanceKeys[inst] = ik.ToString(); SetParentClass(inst, pclass); - ik._inst = inst; ik._parentClassInstance = pclass; _derivedData[inst] = new Dictionary(); @@ -785,6 +796,17 @@ public abstract class Oms private Dictionary?> _derivedData = new Dictionary?>(); public Dictionary? GetDerivedData(IInstanceReference source) { + if (_derivedInstanceKeys.ContainsKey(source)) + { + InstanceKey ik = InstanceKey.Parse(_derivedInstanceKeys[source]); + ik._oms = this; + + Dictionary dd = ik.GetDerivedData(this); + if (dd != null) + { + return dd; + } + } if (IsDerivedInstance(source)) { if (!_derivedData.ContainsKey(source.GetHandle())) @@ -1404,8 +1426,8 @@ public abstract class Oms } if (retval == null) { - return InstanceHandle.Empty; - //throw new NotImplementedException(String.Format("method implementation not found for method class {0}", GetGlobalIdentifier(parentClass))); + // return InstanceHandle.Empty; + throw new NotImplementedException(String.Format("method implementation not found for method class {0}", GetGlobalIdentifier(parentClass))); } else { @@ -2582,6 +2604,10 @@ public abstract class Oms // 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))) { @@ -2590,6 +2616,10 @@ public abstract class Oms // 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))) { @@ -2598,6 +2628,10 @@ public abstract class Oms // 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))) { @@ -2606,6 +2640,10 @@ public abstract class Oms // first check our target instance for the attribute. this MAY be empty value = GetAttributeValue(sourceInstance, workDataInstance); } + else + { + value = context.GetWorkData(workDataInstance); + } } else { diff --git a/mocha-dotnet/src/lib/Mocha.Core/OmsInstanceOpBuilder.cs b/mocha-dotnet/src/lib/Mocha.Core/OmsInstanceOpBuilder.cs new file mode 100644 index 0000000..85ed18b --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Core/OmsInstanceOpBuilder.cs @@ -0,0 +1,38 @@ +using Mocha.Core.Oop; +using Mocha.Core.Oop.InstanceOps; + +namespace Mocha.Core; + +public class OmsInstanceOpBuilder +{ + public Oms Oms { get; } + public OmsInstanceOpBuilder(Oms oms) + { + Oms = oms; + } + + public BuildDynamicInstanceOp CreateBuildDynamicInstanceOp(IInstanceReference buildsInstanceOfClass, IEnumerable> parms) + { + InstanceHandle ih = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.InstanceOpClasses.BuildDynamicInstanceOp)); + Oms.AssignRelationship(ih, Oms.GetInstance(KnownRelationshipGuids.Build_Dynamic_Instance_Op__builds_dynamic__Class), buildsInstanceOfClass); + + List parmAssigns = new List(); + foreach (KeyValuePair kvp in parms) + { + InstanceHandle ihParameterAssignment = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.ParameterAssignment)); + Oms.AssignRelationship(ihParameterAssignment, Oms.GetInstance(KnownRelationshipGuids.Parameter_Assignment__assigns_to__Work_Data), kvp.Key); + Oms.AssignRelationship(ihParameterAssignment, Oms.GetInstance(KnownRelationshipGuids.Parameter_Assignment__assigns_from__Executable_returning_Work_Data), kvp.Value); + parmAssigns.Add(ihParameterAssignment); + } + Oms.AssignRelationship(ih, Oms.GetInstance(KnownRelationshipGuids.Build_Dynamic_Instance_Op__assigns_instance_data_from__Parameter_Assignment), parmAssigns); + + return new BuildDynamicInstanceOp(ih); + } + + public InstanceOp CreateFilterByTypeOp(IInstanceReference usesClass) + { + InstanceHandle iop = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.InstanceOpClasses.FilterByTypeOp)); + Oms.AssignRelationship(iop, Oms.GetInstance(KnownRelationshipGuids.Filter_By_Type_Op__uses__Class), usesClass.GetHandle()); + return new FilterByTypeOp(iop); + } +} \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/OmsMethodBuilder.cs b/mocha-dotnet/src/lib/Mocha.Core/OmsMethodBuilder.cs index 194668d..d8109d4 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/OmsMethodBuilder.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/OmsMethodBuilder.cs @@ -401,4 +401,12 @@ public class OmsMethodBuilder Oms.AssignRelationship(method, Oms.GetInstance(KnownRelationshipGuids.Calculate_Numeric_Method__returns__Numeric_Attribute), returnsAttribute.GetHandle()); return new CalculateNumericMethod(method); } + + public InstanceOpMethod CreateInstanceOpMethod(InstanceHandle forClassInstance, string verb, string name, AccessModifier accessModifier, bool isStatic, WorkSet returnsWorkSet, InstanceOp invokesInstanceOp) + { + InstanceHandle ih = CreateMethodBase(Oms.GetInstance(KnownInstanceGuids.MethodClasses.InstanceOpMethod), forClassInstance, verb, name, accessModifier, isStatic); + Oms.AssignRelationship(ih, Oms.GetInstance(KnownRelationshipGuids.Instance_Op_Method__returns__Work_Set), returnsWorkSet); + Oms.AssignRelationship(ih, Oms.GetInstance(KnownRelationshipGuids.Op_Scope__invokes__Instance_Op), invokesInstanceOp); + return new InstanceOpMethod(ih); + } } \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oop/InstanceOp.cs b/mocha-dotnet/src/lib/Mocha.Core/Oop/InstanceOp.cs new file mode 100644 index 0000000..f6fb2c1 --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Core/Oop/InstanceOp.cs @@ -0,0 +1,6 @@ +namespace Mocha.Core.Oop; + +public class InstanceOp : ConcreteInstanceWrapper +{ + public InstanceOp(InstanceHandle handle) : base(handle) { } +} \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oop/InstanceOps/BuildDynamicInstanceOp.cs b/mocha-dotnet/src/lib/Mocha.Core/Oop/InstanceOps/BuildDynamicInstanceOp.cs new file mode 100644 index 0000000..0f5e36b --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Core/Oop/InstanceOps/BuildDynamicInstanceOp.cs @@ -0,0 +1,6 @@ +namespace Mocha.Core.Oop.InstanceOps; + +public class BuildDynamicInstanceOp : InstanceOp +{ + public BuildDynamicInstanceOp(InstanceHandle handle) : base(handle) { } +} \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oop/InstanceOps/FilterByTypeOp.cs b/mocha-dotnet/src/lib/Mocha.Core/Oop/InstanceOps/FilterByTypeOp.cs new file mode 100644 index 0000000..abe4772 --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Core/Oop/InstanceOps/FilterByTypeOp.cs @@ -0,0 +1,6 @@ +namespace Mocha.Core.Oop.InstanceOps; + +public class FilterByTypeOp : InstanceOp +{ + public FilterByTypeOp(InstanceHandle handle) : base(handle) { } +} \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oop/Methods/InstanceOpMethod.cs b/mocha-dotnet/src/lib/Mocha.Core/Oop/Methods/InstanceOpMethod.cs new file mode 100644 index 0000000..a7b303c --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Core/Oop/Methods/InstanceOpMethod.cs @@ -0,0 +1,13 @@ + +namespace Mocha.Core.Oop.Methods; + +public class InstanceOpMethod : MethodReturningInstanceSet +{ + public InstanceOpMethod(InstanceHandle handle) : base(handle) + { + } + + public override Guid ClassId => KnownInstanceGuids.MethodClasses.InstanceOpMethod; + + +} \ No newline at end of file diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/InstanceOpMethodTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/InstanceOpMethodTests.cs new file mode 100644 index 0000000..3159b52 --- /dev/null +++ b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/InstanceOpMethodTests.cs @@ -0,0 +1,116 @@ +// 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 Mocha.Core.Oop; +using Mocha.Core.Oop.Methods; + +namespace Mocha.Core.Tests.MethodTests +{ + + public class InstanceOpMethodTests : MethodTestsBase + { + [Test] + public void BuildDynamicInstanceOpTest() + { + const string EXPECTED_VALUE = "https://www.mochapowered.com/"; + + InstanceHandle irTestClass = Oms.GetInstance(TEST_CLASS_GUID); + InstanceHandle irTestClassInstance = Oms.CreateInstanceOf(irTestClass); + + InstanceHandle a_Value = Oms.GetInstance(KnownAttributeGuids.Text.Value); + InstanceHandle a_TargetURL = Oms.GetInstance(KnownAttributeGuids.Text.TargetURL); + + Oms.AssignRelationship(irTestClass, Oms.GetInstance(KnownRelationshipGuids.Class__has__Attribute), a_TargetURL); + + OmsInstanceOpBuilder b1 = new OmsInstanceOpBuilder(Oms); + InstanceOp op = b1.CreateBuildDynamicInstanceOp(irTestClass, new KeyValuePair[] + { + new KeyValuePair(a_TargetURL, a_Value) + }); + + OmsMethodBuilder builder = new OmsMethodBuilder(Oms); + + WorkSet iaw_WorkSet = Oms.CreateWorkSet("Work Set for IOP Test"); + InstanceOpMethod ih_IOP = builder.CreateInstanceOpMethod(irTestClass, "build dynamic", "Test Class Instance", AccessModifier.Public, true, iaw_WorkSet, op); + + // set up an OmsContext with `Value` set to our Expected Value + OmsContext context = Oms.CreateContext(); + context.SetWorkData(a_Value, EXPECTED_VALUE); + + // Execute the `Test Class@build dynamic Test Class Instance` with the above instance op + InstanceHandle ih_test = Oms.Execute(context, ih_IOP); + object value = context.GetWorkData(iaw_WorkSet); + InstanceKey ikValue = Oms.GetInstanceKey((InstanceHandle)value); + + string targetUrl = Oms.GetAttributeValue((InstanceHandle)value, a_TargetURL); + // here a_TargetURL should == a_Value + Assert.That(targetUrl, Is.EqualTo(EXPECTED_VALUE)); + } + + [Test] + public void FilterByTypeOpTest() + { + InstanceHandle c_Attribute = Oms.GetInstance(KnownInstanceGuids.Classes.Attribute); + + InstanceHandle c_TextAttribute = Oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute); + InstanceHandle c_BooleanAttribute = Oms.GetInstance(KnownInstanceGuids.Classes.BooleanAttribute); + InstanceHandle c_NumericAttribute = Oms.GetInstance(KnownInstanceGuids.Classes.NumericAttribute); + InstanceHandle c_DateAttribute = Oms.GetInstance(KnownInstanceGuids.Classes.DateAttribute); + + InstanceHandle ihDate1 = Oms.CreateInstanceOf(c_DateAttribute); + InstanceHandle ihDate2 = Oms.CreateInstanceOf(c_DateAttribute); + + InstanceHandle[] irAttributes = new InstanceHandle[] + { + Oms.CreateInstanceOf(c_TextAttribute), + Oms.CreateInstanceOf(c_TextAttribute), + Oms.CreateInstanceOf(c_BooleanAttribute), + Oms.CreateInstanceOf(c_BooleanAttribute), + Oms.CreateInstanceOf(c_BooleanAttribute), + Oms.CreateInstanceOf(c_TextAttribute), + Oms.CreateInstanceOf(c_NumericAttribute), + ihDate1, + ihDate2, + Oms.CreateInstanceOf(c_BooleanAttribute) + }; + + // Filter by Type Op hardcodes `Set` as its Work Set because it doesn't seem to have the ability to accept an arbitrary Work Set + WorkSet wsSrc = Oms.GetInstance(KnownInstanceGuids.WorkSets.Set); + WorkSet wsDst = Oms.CreateWorkSet("Test Work Set for IOP"); + + InstanceOp filterByTypeOp_DateAttribute = (new OmsInstanceOpBuilder(Oms)).CreateFilterByTypeOp(c_DateAttribute); + + OmsMethodBuilder builder = Oms.MethodBuilder; + InstanceOpMethod ih_IOP = builder.CreateInstanceOpMethod(c_Attribute, "get", "Date Attributes", AccessModifier.Public, true, wsDst, filterByTypeOp_DateAttribute); + ReturnInstanceSetMethodBinding rsmb = ih_IOP.CreateMethodBinding(Oms, new KeyValuePair[] + { + // new KeyValuePair(wsSrc.GetHandle(), irAttributes) + }); + + OmsContext context = Oms.CreateContext(); + context.SetWorkData(wsSrc, irAttributes); + + Oms.Execute(context, rsmb); + + IEnumerable data = context.GetWorkData>(wsDst); + + Assert.That(data.Count(), Is.EqualTo(2)); + Assert.That(data.Contains(ihDate1) && data.Contains(ihDate2)); + } + } + +} \ No newline at end of file