diff --git a/mocha-common b/mocha-common index 15db6ef..78649bc 160000 --- a/mocha-common +++ b/mocha-common @@ -1 +1 @@ -Subproject commit 15db6ef037159d1efed4f372d50deb5b6ec33cef +Subproject commit 78649bc72e2dd513f5dedc9103fb765b968399e3 diff --git a/mocha-dotnet.sln b/mocha-dotnet.sln index d7d2349..0564e7d 100644 --- a/mocha-dotnet.sln +++ b/mocha-dotnet.sln @@ -51,6 +51,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mocha.Zq.Tests", "mocha-dot EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mocha.Zq.Integration", "mocha-dotnet\src\lib\Mocha.Zq.Integration\Mocha.Zq.Integration.csproj", "{ADD7359E-0E3B-4435-B812-EC961C52DA2A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mocha.Oms.Server.Tests", "mocha-dotnet\tests\Mocha.Oms.Server.Tests\Mocha.Oms.Server.Tests.csproj", "{271CBF6A-07E4-46EB-A418-513E9FD89E36}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -101,6 +103,10 @@ Global {ADD7359E-0E3B-4435-B812-EC961C52DA2A}.Debug|Any CPU.Build.0 = Debug|Any CPU {ADD7359E-0E3B-4435-B812-EC961C52DA2A}.Release|Any CPU.ActiveCfg = Release|Any CPU {ADD7359E-0E3B-4435-B812-EC961C52DA2A}.Release|Any CPU.Build.0 = Release|Any CPU + {271CBF6A-07E4-46EB-A418-513E9FD89E36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {271CBF6A-07E4-46EB-A418-513E9FD89E36}.Debug|Any CPU.Build.0 = Debug|Any CPU + {271CBF6A-07E4-46EB-A418-513E9FD89E36}.Release|Any CPU.ActiveCfg = Release|Any CPU + {271CBF6A-07E4-46EB-A418-513E9FD89E36}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -127,6 +133,7 @@ Global {04985CF7-45AA-4C67-9EEC-BDDF2DFC5C98} = {A2C401E9-FED4-43BA-A928-566239894CEE} {F5D1EF0F-B42F-4237-B08A-7A78143C3ECB} = {27C300F5-5172-4225-A6F7-3503B9007DD8} {ADD7359E-0E3B-4435-B812-EC961C52DA2A} = {A2C401E9-FED4-43BA-A928-566239894CEE} + {271CBF6A-07E4-46EB-A418-513E9FD89E36} = {27C300F5-5172-4225-A6F7-3503B9007DD8} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {D28A9CF8-0235-4F8F-865F-C460BDCAE16D} diff --git a/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs b/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs index 3be68a3..aa870db 100644 --- a/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs +++ b/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs @@ -1,4 +1,4 @@ -namespace Mocha.OMS.Server; +namespace Mocha.Oms.Server; using Mocha.Core; @@ -42,12 +42,12 @@ public class Program : WebApplication public Program() { ShortName = "mocha-oms-server"; - oms = new MemoryOms(); + Oms = new MemoryOms(); } private LibraryHandle l_System, l_Web; - private Oms oms; + public Oms Oms { get; } protected override WebServer CreateWebServer() { @@ -70,10 +70,10 @@ public class Program : WebApplication } // this all has to be done before the Web server is started... - oms.Initialize(); + Oms.Initialize(); - TenantHandle th = oms.CreateTenant("super"); - oms.SelectTenant(th); + TenantHandle th = Oms.CreateTenant("super"); + Oms.SelectTenant(th); string path; if (System.Environment.OSVersion.Platform == PlatformID.Win32NT) @@ -99,22 +99,22 @@ public class Program : WebApplication return; } - if (!TryLoadLibrary(oms, path, "net.alcetech.Mocha.System.mcl")) + if (!TryLoadLibrary(Oms, path, "net.alcetech.Mocha.System.mcl")) { return; } - if (!TryLoadLibrary(oms, path, "net.alcetech.Mocha.Web.mcl")) + if (!TryLoadLibrary(Oms, path, "net.alcetech.Mocha.Web.mcl")) { return; } // implement functions to get user IP address - oms.RegisterSystemAttributeRoutine(KnownInstanceGuids.SystemAttributeRoutines.GetIPAddress, delegate (Oms oms2, OmsContext ctx2) + Oms.RegisterSystemAttributeRoutine(KnownInstanceGuids.SystemAttributeRoutines.GetIPAddress, delegate (Oms oms2, OmsContext ctx2) { // !HACK return ctx2.GetExtraData("Client.IPAddress"); }); - oms.SystemRoutineExecuted += oms_SystemRoutineExecuted; + Oms.SystemRoutineExecuted += oms_SystemRoutineExecuted; // now we can start the Web server base.OnStartup(e); @@ -158,7 +158,7 @@ public class Program : WebApplication OmsContext ctx = null; if (!e.Context.Session.ContainsKey("OmsContext")) { - ctx = oms.CreateContext(); + ctx = Oms.CreateContext(); e.Context.Session["OmsContext"] = ctx; } ctx = (OmsContext)e.Context.Session["OmsContext"]; @@ -186,7 +186,7 @@ public class Program : WebApplication else if (e.Context.Request.PathParts.Length > 1) { OmsServer server = new OmsServer(); - server.ProcessRequest(e, oms, ctx, sw); + server.ProcessRequest(e, Oms, ctx, sw); } else { diff --git a/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs b/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs index a4442da..25137b4 100755 --- a/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/KnownRelationshipGuids.cs @@ -436,5 +436,7 @@ namespace Mocha.Core 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}"); + + public static Guid Metadata_With_Access_Modifier__has__Access_Modifier { get; } = new Guid("{c8551fb1-6dc5-47cb-8b8f-204d49e6007e}"); } } diff --git a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/EvaluateBooleanExpressionMethodImplementation.cs b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/EvaluateBooleanExpressionMethodImplementation.cs index 949da2d..c082d3e 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/EvaluateBooleanExpressionMethodImplementation.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/EvaluateBooleanExpressionMethodImplementation.cs @@ -92,6 +92,7 @@ public class EvaluateBooleanExpressionMethodImplementation : MethodImplementatio { InstanceHandle target = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Evaluate_Boolean_Expression_Method__has_target__Executable_returning_Work_Data)); InstanceHandle[] rtarget_value = new InstanceHandle[0]; + object? rtarget_valueraw = null; InstanceHandle[] rsource_value = new InstanceHandle[0]; if (rsource_valueraw is InstanceHandle[]) @@ -110,7 +111,7 @@ public class EvaluateBooleanExpressionMethodImplementation : MethodImplementatio else if (oms.IsInstanceOf(target, oms.GetInstance(KnownInstanceGuids.Classes.Executable))) { InstanceHandle rtarget = oms.Execute(context, target); - object? rtarget_valueraw = context.GetWorkData(rtarget); + rtarget_valueraw = context.GetWorkData(rtarget); } else { @@ -151,7 +152,7 @@ public class EvaluateBooleanExpressionMethodImplementation : MethodImplementatio else if (comparison == oms.GetInstance(KnownInstanceGuids.LogicalOperators.EqualTo)) { // ! FIXME ! Implement This ! - value = false; + value = (rsource_valueraw?.Equals(rtarget_valueraw)).GetValueOrDefault(false); } else { diff --git a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/GetAttributeMethodImplementation.cs b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/GetAttributeMethodImplementation.cs index 7560eab..4c0499c 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/GetAttributeMethodImplementation.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/GetAttributeMethodImplementation.cs @@ -30,15 +30,15 @@ public class GetAttributeMethodImplementation : MethodImplementation throw new InvalidOperationException("no Work Set specified for method"); } - InstanceHandle? forInstance = (InstanceHandle?) context.GetWorkData(irForClass); + IInstanceReference? forInstance = (IInstanceReference?) context.GetWorkData(irForClass); if (forInstance == null) { throw new NullReferenceException(String.Format("non-static method call without instance reference {0}", oms.GetGlobalIdentifier(irForClass))); } - if (oms.IsInstanceOf(forInstance.Value, oms.GetInstance(KnownInstanceGuids.Classes.WorkSet))) + if (oms.IsInstanceOf(forInstance, oms.GetInstance(KnownInstanceGuids.Classes.WorkSet))) { - forInstance = (InstanceHandle?) context.GetWorkData(forInstance.Value); + forInstance = (InstanceHandle?) context.GetWorkData(forInstance); } if (forInstance is InstanceHandle forInstanceHandle) diff --git a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/GetRelationshipMethodImplementation.cs b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/GetRelationshipMethodImplementation.cs index f5ccd4f..a54d14f 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/GetRelationshipMethodImplementation.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/MethodImplementations/GetRelationshipMethodImplementation.cs @@ -28,7 +28,7 @@ public class GetRelationshipMethodImplementation : MethodImplementation InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class)); - InstanceHandle? forClassInstanceV = context.GetWorkData(irForClass); + IInstanceReference? forClassInstanceV = context.GetWorkData(irForClass); bool singular = oms.GetAttributeValue(method, oms.GetInstance(KnownAttributeGuids.Boolean.Singular), false); @@ -43,7 +43,7 @@ public class GetRelationshipMethodImplementation : MethodImplementation // HACK: there is no `GR - Get Relationship Method.returns Work Set` if (forClassInstanceV != null) { - ihs = oms.GetRelatedInstances((InstanceHandle)forClassInstanceV, returnsRelationship); + ihs = oms.GetRelatedInstances(forClassInstanceV, returnsRelationship); } if (singular) diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs index 47ea475..a69542a 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs @@ -17,25 +17,13 @@ namespace Mocha.Core; -using System.Collections.ObjectModel; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using System.Data.SqlTypes; -using System.Diagnostics; -using System.Diagnostics.Contracts; -using System.Net; -using System.Numerics; using System.Reflection; -using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using System.Text.Json.Nodes; -using System.Xml.XPath; using MBS.Core; using MBS.Core.Collections; using MBS.Core.Extensibility; -using MBS.Core.IO; -using Mocha.Core.MethodImplementations; using Mocha.Core.Oop; using Mocha.Core.Responses; using Mocha.Core.UI; @@ -485,11 +473,11 @@ public abstract class Oms } protected abstract IReadOnlyCollection GetRelatedInstancesInternal(InstanceHandle source, InstanceHandle relationship, DateTime effectiveDate); - public IReadOnlyCollection GetRelatedInstances(InstanceHandle source, InstanceHandle relationship, DateTime effectiveDate) + public IReadOnlyCollection GetRelatedInstances(IInstanceReference source, InstanceHandle relationship, DateTime effectiveDate) { - return GetRelatedInstancesInternal(source, relationship, effectiveDate); + return GetRelatedInstancesInternal(source.GetHandle(), relationship, effectiveDate); } - public IReadOnlyCollection GetRelatedInstances(InstanceHandle source, InstanceHandle relationship) + public IReadOnlyCollection GetRelatedInstances(IInstanceReference source, InstanceHandle relationship) { return GetRelatedInstances(source, relationship, DateTime.Now); } @@ -845,7 +833,7 @@ public abstract class Oms return false; } - private bool RecursiveClassHasSuperclass(InstanceHandle clasz, InstanceHandle superclasz) + private bool RecursiveClassHasSuperclass(IInstanceReference clasz, InstanceHandle superclasz) { IEnumerable inheritedClasses = GetRelatedInstances(clasz, GetInstance(KnownRelationshipGuids.Class__has_super__Class)); foreach (InstanceHandle ih in inheritedClasses) @@ -862,7 +850,7 @@ public abstract class Oms return false; } - public bool IsInstanceOf(InstanceHandle instance, InstanceHandle parentClass, bool exactMatch = false) + public bool IsInstanceOf(IInstanceReference instance, InstanceHandle parentClass, bool exactMatch = false) { InstanceHandle parentClass1 = GetParentClass(instance); bool value = Object.Equals(parentClass1, parentClass); @@ -873,7 +861,7 @@ public abstract class Oms return value; } - public bool IsSubclassOf(InstanceHandle subclasz, InstanceHandle clasz, bool exactMatch = false) + public bool IsSubclassOf(IInstanceReference subclasz, InstanceHandle clasz, bool exactMatch = false) { bool value = Object.Equals(subclasz, clasz); if (!value && !exactMatch) @@ -1093,12 +1081,12 @@ public abstract class Oms } return defaultValue; } - public InstanceHandle Execute(OmsContext context, InstanceHandle methodOrMethodBinding, InstanceHandle? targetInstance = null) + public InstanceHandle Execute(OmsContext context, InstanceHandle methodOrMethodBinding, IInstanceReference? targetInstance = null) { InstanceHandle parentClass = GetParentClass(methodOrMethodBinding); Guid parentClassId = GetGlobalIdentifier(parentClass); - context.Push(methodOrMethodBinding); + context.Push(methodOrMethodBinding, targetInstance); // context.StackTrace.Push(methodOrMethodBinding); InstanceHandle? retval = null; @@ -1115,14 +1103,27 @@ public abstract class Oms { InstanceHandle assignsToParm = GetRelatedInstance(parm, GetInstance(KnownRelationshipGuids.Parameter_Assignment__assigns_to__Work_Data)); - InstanceHandle assignsFromWorkData = GetRelatedInstance(parm, GetInstance(KnownRelationshipGuids.Parameter_Assignment__assigns_from__Executable_returning_Work_Data)); + IInstanceReference assignsFromWorkData = GetRelatedInstance(parm, GetInstance(KnownRelationshipGuids.Parameter_Assignment__assigns_from__Executable_returning_Work_Data)); if (IsInstanceOf(assignsFromWorkData, GetInstance(KnownInstanceGuids.Classes.Class))) { - assignsFromWorkData = context.GetWorkData(assignsFromWorkData); + assignsFromWorkData = context.GetWorkData(assignsFromWorkData); } context.SetWorkData(assignsToParm, assignsFromWorkData); } - retval = ExecuteMethodBinding(context, methodOrMethodBinding); + + InstanceHandle relatedMethod = GetRelatedInstance(methodOrMethodBinding, GetInstance(KnownRelationshipGuids.Method_Binding__executes__Method)); + InstanceHandle relatedMethod_for_Class = GetRelatedInstance(relatedMethod, GetInstance(KnownRelationshipGuids.Method__for__Class)); + if (relatedMethod_for_Class != InstanceHandle.Empty) + { + //!HACK! + object? wd = context.GetWorkData(relatedMethod_for_Class); + if (wd is IInstanceReference) + { + targetInstance = ((IInstanceReference)context.GetWorkData(relatedMethod_for_Class)).GetHandle(); + } + } + + retval = ExecuteMethodBinding(context, methodOrMethodBinding, targetInstance); InstanceHandle ihSuperRSMB = GetRelatedInstance(methodOrMethodBinding, GetInstance(KnownRelationshipGuids.Method_Binding__uses_super__Return_Instance_Set_Method_Binding)); if (ihSuperRSMB != InstanceHandle.Empty) @@ -1150,10 +1151,56 @@ public abstract class Oms { if (methodImplementations.ContainsKey(parentClassId)) { + if (targetInstance == null) + { + InstanceHandle forClass = GetRelatedInstance(methodOrMethodBinding, GetInstance(KnownRelationshipGuids.Method__for__Class)); + if (forClass != InstanceHandle.Empty) + { + IInstanceReference? irTarget = context.GetWorkData(forClass); + if (irTarget != null) + { + targetInstance = irTarget.GetHandle(); + } + } + } + + bool is_static = GetAttributeValue(methodOrMethodBinding, GetInstance(KnownAttributeGuids.Boolean.Static)); + if (!is_static && targetInstance == null) + { + throw new NullReferenceException(String.Format("Attempt to call instance method `{0}` without an instance", methodOrMethodBinding)); + } + + if (targetInstance == null) + { + + } + + InstanceHandle i_ForClass = GetRelatedInstance(methodOrMethodBinding, GetInstance(KnownRelationshipGuids.Method__for__Class)); + InstanceHandle i_AccessModifier = GetRelatedInstance(methodOrMethodBinding, GetInstance(KnownRelationshipGuids.Metadata_With_Access_Modifier__has__Access_Modifier)); + if (i_AccessModifier == GetInstance(KnownInstanceGuids.AccessModifiers.Private)) + { + // private methods may not be called from outside the defining class + if (context.StackTrace.Count > 2) + { + InstanceHandle caller = context.StackTrace.Peek(); + InstanceHandle caller2 = context.StackTrace.Peek(1); + } + else + { + // we are either a method or a method binding calling a method + // which is an entry point. we do not originate from + // the defining class, so block this call + throw new MethodAccessException("calling entry point method or method binding outside of defining class"); + } + } + else if (i_AccessModifier == GetInstance(KnownInstanceGuids.AccessModifiers.Protected)) + { + // protected methods may be called only from within the defining class or its subclasses + } if (targetInstance != null) { - InstanceHandle hh = targetInstance.GetValueOrDefault(); + InstanceHandle hh = targetInstance.GetHandle(); InstanceHandle pclassInstance = GetParentClass(hh); context.SetWorkData(pclassInstance, hh); } @@ -1178,10 +1225,10 @@ public abstract class Oms } } - private InstanceHandle ExecuteMethodBinding(OmsContext context, InstanceHandle methodBinding) + private InstanceHandle ExecuteMethodBinding(OmsContext context, InstanceHandle methodBinding, IInstanceReference? targetInstance = null) { InstanceHandle method = GetRelatedInstance(methodBinding, GetInstance(KnownRelationshipGuids.Method_Binding__executes__Method)); - return Execute(context, method); + return Execute(context, method, targetInstance); } public OmsContext CreateContext() @@ -1288,7 +1335,7 @@ public abstract class Oms OmsContext context = CreateContext(); context.SetWorkData(parentClass, inst); - InstanceHandle wd = Execute(context, ramb); + InstanceHandle wd = Execute(context, ramb, inst); string value = context.GetWorkData(wd); return value; diff --git a/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs b/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs index 5e0b1c1..fa6b840 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs @@ -25,8 +25,21 @@ public class OmsContext { public Oms Oms { get; } public OmsStackTrace StackTrace { get; } + private Stack TargetInstances = new Stack(); private Stack> WorkDataSets = new Stack>(); + public IInstanceReference? TargetInstance + { + get + { + if (TargetInstances.Count > 0) + { + return TargetInstances.Peek(); + } + return null; + } + } + internal OmsContext(Oms oms) { Oms = oms; @@ -35,26 +48,47 @@ public class OmsContext private Dictionary _WorkData = new Dictionary(); private Dictionary _GlobalData = new Dictionary(); - public object? GetWorkData(WorkSet parm) + public object? GetWorkData(IInstanceReference parm) { - return GetWorkData(parm.GetHandle()); - } - public object? GetWorkData(InstanceHandle parm) - { - if (_WorkData.ContainsKey(parm)) - return _WorkData[parm]; + if (_WorkData.ContainsKey(parm.GetHandle())) + return _WorkData[parm.GetHandle()]; foreach (Dictionary set in WorkDataSets) { - if (set.ContainsKey(parm)) - return set[parm]; + if (set.ContainsKey(parm.GetHandle())) + { + object? val = set[parm.GetHandle()]; + if (val != null) + { + return val; + } + } + } + + foreach (KeyValuePair kvp in _WorkData) + { + if (Oms.IsSubclassOf(kvp.Key, parm.GetHandle())) + { + return kvp.Value; + } + } + + foreach (Dictionary set in WorkDataSets) + { + foreach (KeyValuePair kvp in set) + { + if (Oms.IsSubclassOf(kvp.Key, parm.GetHandle())) + { + return kvp.Value; + } + } } // Console.Error.WriteLine("work data not found for parm {0}", Oms.GetGlobalIdentifier(parm)); return null; } - public T GetWorkData(InstanceHandle parm, T defaultValue = default(T)) + public T GetWorkData(IInstanceReference parm, T defaultValue = default(T)) { object? val = GetWorkData(parm); if (val is T) @@ -64,7 +98,7 @@ public class OmsContext return defaultValue; } - public void SetWorkData(WorkSet parm, object? value) + public void SetWorkData(IInstanceReference parm, object? value) { SetWorkData(parm.GetHandle(), value); } @@ -147,10 +181,11 @@ public class OmsContext _WorkData[parm] = value; } - public void Push(InstanceHandle methodOrMethodBinding) + public void Push(InstanceHandle methodOrMethodBinding, IInstanceReference? targetInstance = null) { StackTrace.Push(methodOrMethodBinding); WorkDataSets.Push(_WorkData); + TargetInstances.Push(targetInstance); _WorkData = new Dictionary(); } @@ -158,6 +193,8 @@ public class OmsContext { InstanceHandle methodOrMethodBinding = StackTrace.Pop(); _WorkData = WorkDataSets.Pop(); + TargetInstances.Pop(); + return methodOrMethodBinding; } diff --git a/mocha-dotnet/src/lib/Mocha.Core/OmsMethodBuilder.cs b/mocha-dotnet/src/lib/Mocha.Core/OmsMethodBuilder.cs index d9b8dfc..4c835b4 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/OmsMethodBuilder.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/OmsMethodBuilder.cs @@ -109,6 +109,10 @@ public class OmsMethodBuilder { InstanceHandle method = Oms.CreateInstanceOf(methodClassInstance, globalIdentifier); Oms.AssignRelationship(method, Oms.GetInstance(KnownRelationshipGuids.Method__for__Class), forClassInstance); + if (accessModifier != null) + { + Oms.AssignRelationship(method, Oms.GetInstance(KnownRelationshipGuids.Metadata_With_Access_Modifier__has__Access_Modifier), accessModifier.GetHandle()); + } if (!Oms.ValidateConstraints) { // sibling relationships aren't being generated automatically diff --git a/mocha-dotnet/src/lib/Mocha.Core/OmsStackTrace.cs b/mocha-dotnet/src/lib/Mocha.Core/OmsStackTrace.cs index c746c42..98ce579 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/OmsStackTrace.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/OmsStackTrace.cs @@ -22,6 +22,7 @@ namespace Mocha.Core; public class OmsStackTrace { private Stack stack = new Stack(); + public int Count { get { return stack.Count; } } private OmsContext parent; internal OmsStackTrace(OmsContext parent) @@ -53,4 +54,14 @@ public class OmsStackTrace } return sb.ToString(); } + + public InstanceHandle Peek(int level = 0) + { + if (level == 0) + { + InstanceHandle ih = stack.Peek(); + return ih; + } + return stack.ElementAt(level); + } } \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Zq.Integration/ZqIntegrator.cs b/mocha-dotnet/src/lib/Mocha.Zq.Integration/ZqIntegrator.cs index 2a989d9..2f5e666 100644 --- a/mocha-dotnet/src/lib/Mocha.Zq.Integration/ZqIntegrator.cs +++ b/mocha-dotnet/src/lib/Mocha.Zq.Integration/ZqIntegrator.cs @@ -42,6 +42,7 @@ public class ZqIntegrator } } + InstanceHandle a_Name = OMS.GetInstance(KnownAttributeGuids.Text.Name); InstanceKey parentIK = OMS.GetInstanceKey(ih); foreach (ZqInstance inst in zql.Instances) { @@ -51,7 +52,6 @@ public class ZqIntegrator OMS.SetInstanceKey(ih2, inst.InstanceKey); } - InstanceHandle a_Name = OMS.GetInstance(KnownAttributeGuids.Text.Name); if (a_Name != InstanceHandle.Empty) { if (inst.Name != null) @@ -65,6 +65,15 @@ public class ZqIntegrator { if (meth is ZqSimpleReturnMethod gsi) { + AccessModifier? accessModifier; + switch (meth.AccessModifier) + { + case ZqAccessModifier.Private: accessModifier = AccessModifier.Private; break; + case ZqAccessModifier.Protected: accessModifier = AccessModifier.Protected; break; + case ZqAccessModifier.Public: accessModifier = AccessModifier.Public; break; + default: accessModifier = AccessModifier.RootA2; break; + } + Core.Oop.WorkSet ws = OMS.CreateWorkSet(meth.Name); if (gsi.ReturnValue is ZqArray) { @@ -81,14 +90,14 @@ public class ZqIntegrator } } - OMS.MethodBuilder.CreateGetSpecifiedInstancesMethod(ih.GetHandle(), null, meth.Name, ws, list.ToArray()); + OMS.MethodBuilder.CreateGetSpecifiedInstancesMethod(ih.GetHandle(), null, meth.Name, accessModifier, meth.IsStatic, ws, list.ToArray()); } else if (gsi.ReturnValue is ZqVariableReference) { object r = ResolveVariable(ih, ((ZqVariableReference)gsi.ReturnValue).Name); if (r is InstanceHandle ihret) { - OMS.MethodBuilder.CreateGetSpecifiedInstancesMethod(ih.GetHandle(), null, meth.Name, ws, ihret); + OMS.MethodBuilder.CreateGetSpecifiedInstancesMethod(ih.GetHandle(), null, meth.Name, accessModifier, meth.IsStatic, ws, ihret); } } } @@ -98,7 +107,7 @@ public class ZqIntegrator return null; } - private object ResolveVariable(Class parentClassInstance, string name) + public object ResolveVariable(Class parentClassInstance, string name) { InstanceHandle ihret = OMS.GetInstanceByName(parentClassInstance, name); if (ihret != InstanceHandle.Empty) @@ -183,7 +192,7 @@ public class ZqIntegrator throw new NotImplementedException(); } - private string ZqNormalizeName(string fullName) + public string ZqNormalizeName(string fullName) { return fullName.Replace("-", "_").Replace(" ", "").Replace("(", "_").Replace(")", "_"); } diff --git a/mocha-dotnet/src/lib/Mocha.Zq/ZqMethod.cs b/mocha-dotnet/src/lib/Mocha.Zq/ZqMethod.cs index 45644e1..2eb1ca9 100644 --- a/mocha-dotnet/src/lib/Mocha.Zq/ZqMethod.cs +++ b/mocha-dotnet/src/lib/Mocha.Zq/ZqMethod.cs @@ -45,6 +45,9 @@ public abstract class ZqMethod : ZqObject, IZqMethod public ZqMethodCall? Executable { get; internal set; } = null; public virtual ZqDataType ReturnDataType { get; set; } + public bool IsStatic { get; set; } + public ZqAccessModifier AccessModifier { get; set; } + public ZqMethod(string name) { Name = name; diff --git a/mocha-dotnet/src/lib/Mocha.Zq/ZqParser.cs b/mocha-dotnet/src/lib/Mocha.Zq/ZqParser.cs index d99b539..a217276 100644 --- a/mocha-dotnet/src/lib/Mocha.Zq/ZqParser.cs +++ b/mocha-dotnet/src/lib/Mocha.Zq/ZqParser.cs @@ -239,7 +239,7 @@ public class ZqParser } else if (tok.Equals("function")) { - return ParseFunction(text, ref i, ref parms); + ZqMethod? p = ParseFunction(text, ref i, ref parms); } else if (tok.Equals("}")) { @@ -251,9 +251,15 @@ public class ZqParser return thisClass; } - private ZqObject? ParseFunction2(string text, ref int i, ref ZqDefParms parms) + private ZqMethod? ParseFunction(string text, ref int i, ref ZqDefParms parms) { - throw new NotImplementedException(); + ZqMethod? p = ParseFunction2(text, ref i, ref parms); + if (p != null) + { + p.IsStatic = parms.isStatic; + p.AccessModifier = parms.accessModifier; + } + return p; } private bool IsModifier(string? tok, ref ZqDefParms parms) @@ -437,7 +443,7 @@ public class ZqParser } } - private ZqMethod? ParseFunction(string pp, ref int j, ref ZqDefParms defparms) + private ZqMethod? ParseFunction2(string pp, ref int j, ref ZqDefParms defparms) { string functionName = ReadUntil(pp, ref j, '(', false).Trim(); List parmListList = new List(); diff --git a/mocha-dotnet/src/plugins/Mocha.Plugins.Libraries.McxMini/McxMiniPlugin.cs b/mocha-dotnet/src/plugins/Mocha.Plugins.Libraries.McxMini/McxMiniPlugin.cs index 2d76865..9360e94 100644 --- a/mocha-dotnet/src/plugins/Mocha.Plugins.Libraries.McxMini/McxMiniPlugin.cs +++ b/mocha-dotnet/src/plugins/Mocha.Plugins.Libraries.McxMini/McxMiniPlugin.cs @@ -184,7 +184,7 @@ public class McxMiniLibraryPlugin : LibraryPlugin protected override void LoadInternal(string filename, Library library) { - FileStream fs = File.Open(filename, FileMode.Open); + FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read); LoadInternal(fs, library); } } diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/BasicTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/BasicTests.cs index f1d4251..1d30262 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/BasicTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/BasicTests.cs @@ -48,7 +48,7 @@ public class BasicTests : OmsTestsBase InstanceHandle irTestClass = Oms.GetInstance(TEST_CLASS_GUID); Assert.That(irTestClass, Is.Not.EqualTo(InstanceHandle.Empty)); - InstanceHandle irTestAttribute = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute), TEST_ATTR_GUID); + InstanceHandle irTestAttribute = Oms.GetInstance(TEST_ATTR_GUID); Assert.That(irTestAttribute, Is.Not.EqualTo(InstanceHandle.Empty)); Oms.AddAttribute(irTestClass, irTestAttribute); diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/DerivedInstanceTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/DerivedInstanceTests.cs index d32a6a9..a07810b 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/DerivedInstanceTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/DerivedInstanceTests.cs @@ -7,11 +7,15 @@ namespace Mocha.Core.Tests; public class DerivedInstanceTests : OmsTestsBase { Class TEST_CLASS_DERIVED; + InstanceKey ik_derived; + protected override void AfterSetup() { base.AfterSetup(); TEST_CLASS_DERIVED = Oms.CreateClass("Test Class (Derived)"); + ik_derived = Oms.GetInstanceKey(TEST_CLASS_DERIVED); + Oms.SetAttributeValue(TEST_CLASS_DERIVED, Oms.GetInstance(KnownAttributeGuids.Boolean.Derived), true); // Derived classes are represented only by InstanceKeys with the form {ClassId}!{DerivedData}, where @@ -43,7 +47,7 @@ public class DerivedInstanceTests : OmsTestsBase [Test] public void Derived_Instance_Test__instance_key_Parse() { - string ikStr = "154!FQAAABVUZXN0IENsYXNzIERlcml2ZWQgIzE="; + string ikStr = String.Format("{0}!FQAAABVUZXN0IENsYXNzIERlcml2ZWQgIzE=", ik_derived.InstanceIndex); InstanceKey ik = InstanceKey.Parse(ikStr); InstanceHandle ih = Oms.GetInstance(ik); diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/EvaluateBooleanExpressionMethodTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/EvaluateBooleanExpressionMethodTests.cs index b483986..6b6175f 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/EvaluateBooleanExpressionMethodTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/EvaluateBooleanExpressionMethodTests.cs @@ -22,6 +22,24 @@ namespace Mocha.Core.Tests.MethodTests; public class EvaluateBooleanExpressionMethodTests : MethodTestsBase { + [Test] + public void Test_EBE_Method__is__Static() + { + InstanceHandle c_OMS = Oms.GetInstance(KnownInstanceGuids.Classes.OMS); + InstanceHandle c_Method = Oms.GetInstance(KnownInstanceGuids.Classes.Method); + + Method OMS__get__Runtime_Version = Oms.GetMethod(c_OMS, "get", "Runtime Version"); + + MethodReturningAttribute Method__is__Static = (MethodReturningAttribute) Oms.GetMethod(c_Method, "is", "Static"); + MethodBinding mb = Method__is__Static.CreateMethodBinding(Oms); + + + OmsContext context = Oms.CreateContext(); + InstanceHandle h = Oms.Execute(context, mb, OMS__get__Runtime_Version); + object? val = context.GetWorkData(h); + Assert.That(val, Is.EqualTo(true)); + } + [Test] public void Test_EBE_Returns_False_if_Method_is_NOT_Get_Attribute_Method() { @@ -37,7 +55,7 @@ public class EvaluateBooleanExpressionMethodTests : MethodTestsBase context.SetWorkData(c_Instance, Instance__get__Parent_Class); InstanceHandle wsRet = Oms.Execute(context, Instance__get__Parent_Class); - InstanceHandle pclass = (InstanceHandle)context.GetWorkData(wsRet); + object? pclass = context.GetWorkData(wsRet); Assert.That(pclass, Is.EqualTo(Oms.GetInstance(KnownInstanceGuids.MethodClasses.GetRelationshipMethod))); diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/GetAttributeMethodTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/GetAttributeMethodTests.cs index 564137b..c16db26 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/GetAttributeMethodTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/GetAttributeMethodTests.cs @@ -29,7 +29,7 @@ namespace Mocha.Core.Tests.MethodTests InstanceHandle irTestClass = Oms.GetInstance(TEST_CLASS_GUID); InstanceHandle irTestClassInstance = Oms.CreateInstanceOf(irTestClass); - InstanceHandle irTestAttribute = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute), TEST_ATTR_GUID); + InstanceHandle irTestAttribute = Oms.GetInstance(TEST_ATTR_GUID); Assert.That(irTestAttribute, Is.Not.EqualTo(InstanceHandle.Empty)); Oms.AddAttribute(irTestClass, irTestAttribute); diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/MethodBindingTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/MethodBindingTests.cs index 7f632f8..d71218c 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/MethodBindingTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTests/MethodBindingTests.cs @@ -112,10 +112,10 @@ public class MethodBindingTests : MethodTestsBase WorkSet ws = Oms.CreateWorkSet("Singleton OMS"); - GetSpecifiedInstancesMethod m1 = Oms.MethodBuilder.CreateGetSpecifiedInstancesMethod(c_OMS.GetHandle(), "get", "Singleton", ws, new InstanceHandle[] { i_OMS }); + GetSpecifiedInstancesMethod m1 = Oms.MethodBuilder.CreateGetSpecifiedInstancesMethod(c_OMS.GetHandle(), "get", "Singleton", AccessModifier.Public, true, ws, new InstanceHandle[] { i_OMS }); ReturnInstanceSetMethodBinding rsmb1 = m1.CreateMethodBinding(Oms); - GetSpecifiedInstancesMethod m2 = Oms.MethodBuilder.CreateGetSpecifiedInstancesMethod(c_OMS.GetHandle(), "get", "Singleton 2", ws, new InstanceHandle[] { i_OMS2 }); + GetSpecifiedInstancesMethod m2 = Oms.MethodBuilder.CreateGetSpecifiedInstancesMethod(c_OMS.GetHandle(), "get", "Singleton 2", AccessModifier.Public, true, ws, new InstanceHandle[] { i_OMS2 }); ReturnInstanceSetMethodBinding rsmb2 = m2.CreateMethodBinding(Oms); ReturnInstanceSetMethodBinding rsmb3 = m2.CreateMethodBinding(Oms); diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/MethodTestsBase.cs b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTestsBase.cs index ccf387f..37911fc 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/MethodTestsBase.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/MethodTestsBase.cs @@ -23,8 +23,8 @@ public abstract class MethodTestsBase : OmsTestsBase { Guid gid_r_Test_Class__has__Test_Class_2 = new Guid("{a5b67aad-e46f-4673-b339-77417396b2fe}"); Guid gid_r_Test_Class_2__for__Test_Class = new Guid("{2864dfd9-0313-4801-96bf-b9be99ea172d}"); - Guid gid_r_Test_Class__has_multiple__Test_Class_2 = new Guid("{a5b67aad-e46f-4673-b339-77417396b2fe}"); - Guid gid_r_Test_Class_2__multiple_for__Test_Class = new Guid("{2864dfd9-0313-4801-96bf-b9be99ea172d}"); + Guid gid_r_Test_Class__has_multiple__Test_Class_2 = new Guid("{4c51e214-68c8-4e14-8e94-4e4667f05778}"); + Guid gid_r_Test_Class_2__multiple_for__Test_Class = new Guid("{fcf70fa7-ebd0-438a-a534-ee31dbe3b04f}"); protected Class c_TestClass, c_TestClass2; protected Relationship r_Test_Class__has__Test_Class_2, r_Test_Class_2__for__Test_Class; diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/Oop/AccessModifierTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/Oop/AccessModifierTests.cs new file mode 100644 index 0000000..e008ca6 --- /dev/null +++ b/mocha-dotnet/tests/Mocha.Core.Tests/Oop/AccessModifierTests.cs @@ -0,0 +1,74 @@ +using System; +using Mocha.Core.Oop; +using Mocha.Core.Oop.Methods; + +namespace Mocha.Core.Tests.Oop; + +public class AccessModifierTests : OmsTestsBase +{ + [Test] + public void Public_Static_Method_Called_With_Default_Context_Succeeds() + { + Class c_TestClass = Oms.GetInstance(TEST_CLASS_GUID); + Class c_TestClass2 = Oms.GetInstance(TEST_CLASS2_GUID); + + InstanceHandle a_Value = Oms.GetInstance(KnownAttributeGuids.Text.Value); + + BuildAttributeMethod ba1 = Oms.MethodBuilder.CreateBuildAttributeMethod(c_TestClass.GetHandle(), "get", "Test Text 1", AccessModifier.Public, true, a_Value, "Test Text 1"); + ReturnAttributeMethodBinding ramb1 = ba1.CreateMethodBinding(Oms); + + OmsContext context = Oms.CreateContext(); + string value = Oms.ExecuteReturningAttributeValue(context, ramb1); + Assert.That(value, Is.EqualTo("Test Text 1")); + } + + [Test] + public void Private_Static_Method_Called_Outside_Defining_Class_Fails() + { + Class c_TestClass = Oms.GetInstance(TEST_CLASS_GUID); + Class c_TestClass2 = Oms.GetInstance(TEST_CLASS2_GUID); + + InstanceHandle a_Value = Oms.GetInstance(KnownAttributeGuids.Text.Value); + + BuildAttributeMethod ba1 = Oms.MethodBuilder.CreateBuildAttributeMethod(c_TestClass.GetHandle(), "get", "Test Text 1", AccessModifier.Private, true, a_Value, "Test Text 1"); + ReturnAttributeMethodBinding ramb1 = ba1.CreateMethodBinding(Oms); + + Assert.That(delegate () + { + OmsContext context = Oms.CreateContext(); + string value = Oms.ExecuteReturningAttributeValue(context, ramb1); + Assert.That(value, Is.EqualTo("Test Text 1")); + }, Throws.InstanceOf()); + } + + + [Test] + public void Private_Static_Method_Called_From_Another_Class_Fails() + { + Class c_TestClass = Oms.GetInstance(TEST_CLASS_GUID); + Class c_TestClass2 = Oms.GetInstance(TEST_CLASS2_GUID); + + + InstanceHandle a_Value = Oms.GetInstance(KnownAttributeGuids.Text.Value); + + BuildAttributeMethod ba1 = Oms.MethodBuilder.CreateBuildAttributeMethod(c_TestClass.GetHandle(), "get", "Test Text 1", AccessModifier.Private, true, a_Value, "Test Text 1"); + ReturnAttributeMethodBinding ramb1 = ba1.CreateMethodBinding(Oms); + + InstanceHandle a1 = Oms.GetInstance(KnownAttributeGuids.Text.Value); + + // InstanceHandle usesReferenceInstanceSet = Oms.MethodBuilder.CreateGetRelationshipMethod(c_TestClass.GetHandle(), r_Test_Class_1__get__Test_Class + // GetAttributeMethod ga1 = Oms.MethodBuilder.CreateGetReferencedAttributeMethod(c_TestClass2.GetHandle(), "get", "referenced Test Text 1", AccessModifier.Public, true, a1, usesReferenceInstanceSet, usesAnswerExecutableReturningAttribute, usesAccumulationFunction,usesOrderExecutableReturningAttribute); + + // FIXME: find a way to refer to ^^ BA from another class + // BuildAttributeMethod ga1 = Oms.MethodBuilder.CreateGetReferencedAttributeMethod(c_TestClass2, "get", "Test Text 1 from Test Class 1", AccessModifier.Public, true, a_Value, "Test Text 1"); + // ReturnAttributeMethodBinding ramb2 = ga1.CreateMethodBinding(Oms); + + Assert.That(delegate () + { + OmsContext context = Oms.CreateContext(); + string value = Oms.ExecuteReturningAttributeValue(context, ramb1); + Assert.That(value, Is.EqualTo("Test Text 1")); + }, Throws.InstanceOf()); + } + +} diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/RelationshipTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/RelationshipTests.cs index 7fb0141..4b08758 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/RelationshipTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/RelationshipTests.cs @@ -37,8 +37,9 @@ public class RelationshipTests : OmsTestsBase { InstanceHandle c_Class = Oms.GetInstance(KnownInstanceGuids.Classes.Class); - c_TestClass = Oms.CreateClass("Test Class", TEST_CLASS_GUID); - c_TestClass2 = Oms.CreateClass("Test Class 2", TEST_CLASS2_GUID); + c_TestClass = Oms.GetInstance(TEST_CLASS_GUID); + c_TestClass2 = Oms.GetInstance(TEST_CLASS2_GUID); + c_TestClassInstance = Oms.CreateInstanceOf(c_TestClass); c_TestClass2Instance1 = Oms.CreateInstanceOf(c_TestClass2); diff --git a/mocha-dotnet/tests/Mocha.Oms.Server.Tests/BasicTests.cs b/mocha-dotnet/tests/Mocha.Oms.Server.Tests/BasicTests.cs new file mode 100644 index 0000000..dc413c4 --- /dev/null +++ b/mocha-dotnet/tests/Mocha.Oms.Server.Tests/BasicTests.cs @@ -0,0 +1,125 @@ + +using System.Net; +using System.Net.Http.Json; +using System.Text.Json.Nodes; +using Mocha.Core; +using NUnit.Framework.Interfaces; + +namespace Mocha.Oms.Server.Tests; + +public class Tests +{ + private Thread ServerThread; + private Program program; + + [SetUp] + public void Setup() + { + program = new Program(); + program.SupportEmbeddedHosting = true; + + int exitCode = program.Start(); + } + + [TearDown] + public void TearDown() + { + program.Stop(); + } + + [Test] + public async Task Tenant_List_Test() + { + Assert.That(program, Is.Not.Null); + + HttpClient client = new HttpClient(); + HttpResponseMessage resp = client.Send(new HttpRequestMessage(HttpMethod.Get, BuildUrl("/tenants"))); + + Assert.That(resp.StatusCode, Is.EqualTo(System.Net.HttpStatusCode.OK)); + Assert.That(resp.Content.Headers.ContentType.ToString(), Is.EqualTo("application/json")); + + string content = await resp.Content.ReadAsStringAsync(); + + JsonObject json = JsonNode.Parse(content) as JsonObject; + Assert.That(json["result"].ToString(), Is.EqualTo("success")); + Assert.That(json["tenants"].AsArray().Count, Is.EqualTo(1)); + Assert.That(json["tenants"].AsArray()[0].ToString(), Is.EqualTo("super")); + } + + [Test] + public async Task Instance_Json_Test() + { + Assert.That(program, Is.Not.Null); + + InstanceHandle h = program.Oms.GetInstance(KnownInstanceGuids.Classes.Class); + InstanceKey k = program.Oms.GetInstanceKey(h); + Guid g = program.Oms.GetGlobalIdentifier(h); + string sz = program.Oms.GetInstanceText(h); + + HttpClient client = new HttpClient(); + HttpResponseMessage resp = client.Send(new HttpRequestMessage(HttpMethod.Get, BuildUrl("/tenants/super/instances/1$1"))); + + Assert.That(resp.StatusCode, Is.EqualTo(System.Net.HttpStatusCode.OK)); + Assert.That(resp.Content.Headers.ContentType.ToString(), Is.EqualTo("application/json")); + + string content = await resp.Content.ReadAsStringAsync(); + + JsonObject json = JsonNode.Parse(content) as JsonObject; + Assert.That(InstanceKey.Parse(json["iid"].ToString()), Is.EqualTo(k)); + Assert.That(new Guid(json["globalIdentifier"].ToString()), Is.EqualTo(g)); + Assert.That(json["text"].ToString(), Is.EqualTo(sz)); + } + + [Test, TestCase("1$1"), TestCase("1$2"), TestCase("1$3"), TestCase("4$1"), TestCase("6$3")] + public async Task Instance_Json_Test_Multi(string ik) + { + Assert.That(program, Is.Not.Null); + + InstanceHandle h = program.Oms.GetInstance(InstanceKey.Parse(ik)); + InstanceKey k = program.Oms.GetInstanceKey(h); + Guid g = program.Oms.GetGlobalIdentifier(h); + string sz = program.Oms.GetInstanceText(h); + + HttpClient client = new HttpClient(); + HttpResponseMessage resp = client.Send(new HttpRequestMessage(HttpMethod.Get, BuildUrl(String.Format("/tenants/super/instances/{0}", ik)))); + + Assert.That(resp.StatusCode, Is.EqualTo(System.Net.HttpStatusCode.OK)); + Assert.That(resp.Content.Headers.ContentType.ToString(), Is.EqualTo("application/json")); + + string content = await resp.Content.ReadAsStringAsync(); + + JsonObject json = JsonNode.Parse(content) as JsonObject; + Assert.That(InstanceKey.Parse(json["iid"].ToString()), Is.EqualTo(k)); + Assert.That(new Guid(json["globalIdentifier"].ToString()), Is.EqualTo(g)); + Assert.That(json["text"].ToString(), Is.EqualTo(sz)); + } + + + [Test] + public async Task Element_Test() + { + Assert.That(program, Is.Not.Null); + + InstanceHandle h = program.Oms.GetInstance(KnownInstanceGuids.Classes.Class); + InstanceKey k = program.Oms.GetInstanceKey(h); + Guid g = program.Oms.GetGlobalIdentifier(h); + string sz = program.Oms.GetInstanceText(h); + + HttpClient client = new HttpClient(); + HttpResponseMessage resp = client.Send(new HttpRequestMessage(HttpMethod.Get, BuildUrl("/tenants/super/instances/6$3/element"))); + + Assert.That(resp.StatusCode, Is.EqualTo(System.Net.HttpStatusCode.OK)); + Assert.That(resp.Content.Headers.ContentType.ToString(), Is.EqualTo("application/json")); + + string content = await resp.Content.ReadAsStringAsync(); + + JsonObject json = JsonNode.Parse(content) as JsonObject; + Assert.That(json["result"].ToString(), Is.EqualTo("success")); + Assert.That(json["value"]["widget"].ToString(), Is.EqualTo("root")); + } + + protected string? BuildUrl(string v) + { + return String.Format("http://localhost:{0}{1}", program.Port, v); + } +} \ No newline at end of file diff --git a/mocha-dotnet/tests/Mocha.Oms.Server.Tests/GlobalUsings.cs b/mocha-dotnet/tests/Mocha.Oms.Server.Tests/GlobalUsings.cs new file mode 100644 index 0000000..cefced4 --- /dev/null +++ b/mocha-dotnet/tests/Mocha.Oms.Server.Tests/GlobalUsings.cs @@ -0,0 +1 @@ +global using NUnit.Framework; \ No newline at end of file diff --git a/mocha-dotnet/tests/Mocha.Oms.Server.Tests/Mocha.Oms.Server.Tests.csproj b/mocha-dotnet/tests/Mocha.Oms.Server.Tests/Mocha.Oms.Server.Tests.csproj new file mode 100644 index 0000000..2901ec2 --- /dev/null +++ b/mocha-dotnet/tests/Mocha.Oms.Server.Tests/Mocha.Oms.Server.Tests.csproj @@ -0,0 +1,27 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + + diff --git a/web-framework-dotnet b/web-framework-dotnet index e6b974f..19d4876 160000 --- a/web-framework-dotnet +++ b/web-framework-dotnet @@ -1 +1 @@ -Subproject commit e6b974f6514320f43228da2abdcd0ce66b3c30c1 +Subproject commit 19d487683468db5b7e34d449ac105b088cef9b5a