fix regressions introduced by tighter OOP restrictions and add unit tests for HTTP OMS server

This commit is contained in:
Michael Becker 2025-01-05 23:37:09 -05:00
parent 36b5d8a7c5
commit 3c5bfc6f6a
27 changed files with 457 additions and 80 deletions

@ -1 +1 @@
Subproject commit 15db6ef037159d1efed4f372d50deb5b6ec33cef Subproject commit 78649bc72e2dd513f5dedc9103fb765b968399e3

View File

@ -51,6 +51,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mocha.Zq.Tests", "mocha-dot
EndProject 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}" 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 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 Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU 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}.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.ActiveCfg = Release|Any CPU
{ADD7359E-0E3B-4435-B812-EC961C52DA2A}.Release|Any CPU.Build.0 = 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 EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -127,6 +133,7 @@ Global
{04985CF7-45AA-4C67-9EEC-BDDF2DFC5C98} = {A2C401E9-FED4-43BA-A928-566239894CEE} {04985CF7-45AA-4C67-9EEC-BDDF2DFC5C98} = {A2C401E9-FED4-43BA-A928-566239894CEE}
{F5D1EF0F-B42F-4237-B08A-7A78143C3ECB} = {27C300F5-5172-4225-A6F7-3503B9007DD8} {F5D1EF0F-B42F-4237-B08A-7A78143C3ECB} = {27C300F5-5172-4225-A6F7-3503B9007DD8}
{ADD7359E-0E3B-4435-B812-EC961C52DA2A} = {A2C401E9-FED4-43BA-A928-566239894CEE} {ADD7359E-0E3B-4435-B812-EC961C52DA2A} = {A2C401E9-FED4-43BA-A928-566239894CEE}
{271CBF6A-07E4-46EB-A418-513E9FD89E36} = {27C300F5-5172-4225-A6F7-3503B9007DD8}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D28A9CF8-0235-4F8F-865F-C460BDCAE16D} SolutionGuid = {D28A9CF8-0235-4F8F-865F-C460BDCAE16D}

View File

@ -1,4 +1,4 @@
namespace Mocha.OMS.Server; namespace Mocha.Oms.Server;
using Mocha.Core; using Mocha.Core;
@ -42,12 +42,12 @@ public class Program : WebApplication
public Program() public Program()
{ {
ShortName = "mocha-oms-server"; ShortName = "mocha-oms-server";
oms = new MemoryOms(); Oms = new MemoryOms();
} }
private LibraryHandle l_System, l_Web; private LibraryHandle l_System, l_Web;
private Oms oms; public Oms Oms { get; }
protected override WebServer CreateWebServer() protected override WebServer CreateWebServer()
{ {
@ -70,10 +70,10 @@ public class Program : WebApplication
} }
// this all has to be done before the Web server is started... // this all has to be done before the Web server is started...
oms.Initialize(); Oms.Initialize();
TenantHandle th = oms.CreateTenant("super"); TenantHandle th = Oms.CreateTenant("super");
oms.SelectTenant(th); Oms.SelectTenant(th);
string path; string path;
if (System.Environment.OSVersion.Platform == PlatformID.Win32NT) if (System.Environment.OSVersion.Platform == PlatformID.Win32NT)
@ -99,22 +99,22 @@ public class Program : WebApplication
return; return;
} }
if (!TryLoadLibrary(oms, path, "net.alcetech.Mocha.System.mcl")) if (!TryLoadLibrary(Oms, path, "net.alcetech.Mocha.System.mcl"))
{ {
return; return;
} }
if (!TryLoadLibrary(oms, path, "net.alcetech.Mocha.Web.mcl")) if (!TryLoadLibrary(Oms, path, "net.alcetech.Mocha.Web.mcl"))
{ {
return; return;
} }
// implement functions to get user IP address // implement functions to get user IP address
oms.RegisterSystemAttributeRoutine<string>(KnownInstanceGuids.SystemAttributeRoutines.GetIPAddress, delegate (Oms oms2, OmsContext ctx2) Oms.RegisterSystemAttributeRoutine<string>(KnownInstanceGuids.SystemAttributeRoutines.GetIPAddress, delegate (Oms oms2, OmsContext ctx2)
{ {
// !HACK // !HACK
return ctx2.GetExtraData<string>("Client.IPAddress"); return ctx2.GetExtraData<string>("Client.IPAddress");
}); });
oms.SystemRoutineExecuted += oms_SystemRoutineExecuted; Oms.SystemRoutineExecuted += oms_SystemRoutineExecuted;
// now we can start the Web server // now we can start the Web server
base.OnStartup(e); base.OnStartup(e);
@ -158,7 +158,7 @@ public class Program : WebApplication
OmsContext ctx = null; OmsContext ctx = null;
if (!e.Context.Session.ContainsKey("OmsContext")) if (!e.Context.Session.ContainsKey("OmsContext"))
{ {
ctx = oms.CreateContext(); ctx = Oms.CreateContext();
e.Context.Session["OmsContext"] = ctx; e.Context.Session["OmsContext"] = ctx;
} }
ctx = (OmsContext)e.Context.Session["OmsContext"]; ctx = (OmsContext)e.Context.Session["OmsContext"];
@ -186,7 +186,7 @@ public class Program : WebApplication
else if (e.Context.Request.PathParts.Length > 1) else if (e.Context.Request.PathParts.Length > 1)
{ {
OmsServer server = new OmsServer(); OmsServer server = new OmsServer();
server.ProcessRequest(e, oms, ctx, sw); server.ProcessRequest(e, Oms, ctx, sw);
} }
else else
{ {

View File

@ -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__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 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 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}");
} }
} }

View File

@ -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 target = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Evaluate_Boolean_Expression_Method__has_target__Executable_returning_Work_Data));
InstanceHandle[] rtarget_value = new InstanceHandle[0]; InstanceHandle[] rtarget_value = new InstanceHandle[0];
object? rtarget_valueraw = null;
InstanceHandle[] rsource_value = new InstanceHandle[0]; InstanceHandle[] rsource_value = new InstanceHandle[0];
if (rsource_valueraw is InstanceHandle[]) if (rsource_valueraw is InstanceHandle[])
@ -110,7 +111,7 @@ public class EvaluateBooleanExpressionMethodImplementation : MethodImplementatio
else if (oms.IsInstanceOf(target, oms.GetInstance(KnownInstanceGuids.Classes.Executable))) else if (oms.IsInstanceOf(target, oms.GetInstance(KnownInstanceGuids.Classes.Executable)))
{ {
InstanceHandle rtarget = oms.Execute(context, target); InstanceHandle rtarget = oms.Execute(context, target);
object? rtarget_valueraw = context.GetWorkData(rtarget); rtarget_valueraw = context.GetWorkData(rtarget);
} }
else else
{ {
@ -151,7 +152,7 @@ public class EvaluateBooleanExpressionMethodImplementation : MethodImplementatio
else if (comparison == oms.GetInstance(KnownInstanceGuids.LogicalOperators.EqualTo)) else if (comparison == oms.GetInstance(KnownInstanceGuids.LogicalOperators.EqualTo))
{ {
// ! FIXME ! Implement This ! // ! FIXME ! Implement This !
value = false; value = (rsource_valueraw?.Equals(rtarget_valueraw)).GetValueOrDefault(false);
} }
else else
{ {

View File

@ -30,15 +30,15 @@ public class GetAttributeMethodImplementation : MethodImplementation
throw new InvalidOperationException("no Work Set specified for method"); throw new InvalidOperationException("no Work Set specified for method");
} }
InstanceHandle? forInstance = (InstanceHandle?) context.GetWorkData(irForClass); IInstanceReference? forInstance = (IInstanceReference?) context.GetWorkData(irForClass);
if (forInstance == null) if (forInstance == null)
{ {
throw new NullReferenceException(String.Format("non-static method call without instance reference {0}", oms.GetGlobalIdentifier(irForClass))); 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) if (forInstance is InstanceHandle forInstanceHandle)

View File

@ -28,7 +28,7 @@ public class GetRelationshipMethodImplementation : MethodImplementation
InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class)); InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class));
InstanceHandle? forClassInstanceV = context.GetWorkData<InstanceHandle?>(irForClass); IInstanceReference? forClassInstanceV = context.GetWorkData<IInstanceReference?>(irForClass);
bool singular = oms.GetAttributeValue<bool>(method, oms.GetInstance(KnownAttributeGuids.Boolean.Singular), false); bool singular = oms.GetAttributeValue<bool>(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` // HACK: there is no `GR - Get Relationship Method.returns Work Set`
if (forClassInstanceV != null) if (forClassInstanceV != null)
{ {
ihs = oms.GetRelatedInstances((InstanceHandle)forClassInstanceV, returnsRelationship); ihs = oms.GetRelatedInstances(forClassInstanceV, returnsRelationship);
} }
if (singular) if (singular)

View File

@ -17,25 +17,13 @@
namespace Mocha.Core; 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.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Text.Json.Nodes; using System.Text.Json.Nodes;
using System.Xml.XPath;
using MBS.Core; using MBS.Core;
using MBS.Core.Collections; using MBS.Core.Collections;
using MBS.Core.Extensibility; using MBS.Core.Extensibility;
using MBS.Core.IO;
using Mocha.Core.MethodImplementations;
using Mocha.Core.Oop; using Mocha.Core.Oop;
using Mocha.Core.Responses; using Mocha.Core.Responses;
using Mocha.Core.UI; using Mocha.Core.UI;
@ -485,11 +473,11 @@ public abstract class Oms
} }
protected abstract IReadOnlyCollection<InstanceHandle> GetRelatedInstancesInternal(InstanceHandle source, InstanceHandle relationship, DateTime effectiveDate); protected abstract IReadOnlyCollection<InstanceHandle> GetRelatedInstancesInternal(InstanceHandle source, InstanceHandle relationship, DateTime effectiveDate);
public IReadOnlyCollection<InstanceHandle> GetRelatedInstances(InstanceHandle source, InstanceHandle relationship, DateTime effectiveDate) public IReadOnlyCollection<InstanceHandle> GetRelatedInstances(IInstanceReference source, InstanceHandle relationship, DateTime effectiveDate)
{ {
return GetRelatedInstancesInternal(source, relationship, effectiveDate); return GetRelatedInstancesInternal(source.GetHandle(), relationship, effectiveDate);
} }
public IReadOnlyCollection<InstanceHandle> GetRelatedInstances(InstanceHandle source, InstanceHandle relationship) public IReadOnlyCollection<InstanceHandle> GetRelatedInstances(IInstanceReference source, InstanceHandle relationship)
{ {
return GetRelatedInstances(source, relationship, DateTime.Now); return GetRelatedInstances(source, relationship, DateTime.Now);
} }
@ -845,7 +833,7 @@ public abstract class Oms
return false; return false;
} }
private bool RecursiveClassHasSuperclass(InstanceHandle clasz, InstanceHandle superclasz) private bool RecursiveClassHasSuperclass(IInstanceReference clasz, InstanceHandle superclasz)
{ {
IEnumerable<InstanceHandle> inheritedClasses = GetRelatedInstances(clasz, GetInstance(KnownRelationshipGuids.Class__has_super__Class)); IEnumerable<InstanceHandle> inheritedClasses = GetRelatedInstances(clasz, GetInstance(KnownRelationshipGuids.Class__has_super__Class));
foreach (InstanceHandle ih in inheritedClasses) foreach (InstanceHandle ih in inheritedClasses)
@ -862,7 +850,7 @@ public abstract class Oms
return false; 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); InstanceHandle parentClass1 = GetParentClass(instance);
bool value = Object.Equals(parentClass1, parentClass); bool value = Object.Equals(parentClass1, parentClass);
@ -873,7 +861,7 @@ public abstract class Oms
return value; 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); bool value = Object.Equals(subclasz, clasz);
if (!value && !exactMatch) if (!value && !exactMatch)
@ -1093,12 +1081,12 @@ public abstract class Oms
} }
return defaultValue; 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); InstanceHandle parentClass = GetParentClass(methodOrMethodBinding);
Guid parentClassId = GetGlobalIdentifier(parentClass); Guid parentClassId = GetGlobalIdentifier(parentClass);
context.Push(methodOrMethodBinding); context.Push(methodOrMethodBinding, targetInstance);
// context.StackTrace.Push(methodOrMethodBinding); // context.StackTrace.Push(methodOrMethodBinding);
InstanceHandle? retval = null; InstanceHandle? retval = null;
@ -1115,14 +1103,27 @@ public abstract class Oms
{ {
InstanceHandle assignsToParm = GetRelatedInstance(parm, GetInstance(KnownRelationshipGuids.Parameter_Assignment__assigns_to__Work_Data)); 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))) if (IsInstanceOf(assignsFromWorkData, GetInstance(KnownInstanceGuids.Classes.Class)))
{ {
assignsFromWorkData = context.GetWorkData<InstanceHandle>(assignsFromWorkData); assignsFromWorkData = context.GetWorkData<IInstanceReference>(assignsFromWorkData);
} }
context.SetWorkData(assignsToParm, assignsFromWorkData); context.SetWorkData(assignsToParm, assignsFromWorkData);
} }
retval = ExecuteMethodBinding(context, methodOrMethodBinding);
InstanceHandle relatedMethod = GetRelatedInstance(methodOrMethodBinding, GetInstance<Relationship>(KnownRelationshipGuids.Method_Binding__executes__Method));
InstanceHandle relatedMethod_for_Class = GetRelatedInstance(relatedMethod, GetInstance<Relationship>(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)); InstanceHandle ihSuperRSMB = GetRelatedInstance(methodOrMethodBinding, GetInstance(KnownRelationshipGuids.Method_Binding__uses_super__Return_Instance_Set_Method_Binding));
if (ihSuperRSMB != InstanceHandle.Empty) if (ihSuperRSMB != InstanceHandle.Empty)
@ -1150,10 +1151,56 @@ public abstract class Oms
{ {
if (methodImplementations.ContainsKey(parentClassId)) if (methodImplementations.ContainsKey(parentClassId))
{ {
if (targetInstance == null)
{
InstanceHandle forClass = GetRelatedInstance(methodOrMethodBinding, GetInstance(KnownRelationshipGuids.Method__for__Class));
if (forClass != InstanceHandle.Empty)
{
IInstanceReference? irTarget = context.GetWorkData<IInstanceReference?>(forClass);
if (irTarget != null)
{
targetInstance = irTarget.GetHandle();
}
}
}
bool is_static = GetAttributeValue<bool>(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) if (targetInstance != null)
{ {
InstanceHandle hh = targetInstance.GetValueOrDefault(); InstanceHandle hh = targetInstance.GetHandle();
InstanceHandle pclassInstance = GetParentClass(hh); InstanceHandle pclassInstance = GetParentClass(hh);
context.SetWorkData(pclassInstance, 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)); InstanceHandle method = GetRelatedInstance(methodBinding, GetInstance(KnownRelationshipGuids.Method_Binding__executes__Method));
return Execute(context, method); return Execute(context, method, targetInstance);
} }
public OmsContext CreateContext() public OmsContext CreateContext()
@ -1288,7 +1335,7 @@ public abstract class Oms
OmsContext context = CreateContext(); OmsContext context = CreateContext();
context.SetWorkData(parentClass, inst); context.SetWorkData(parentClass, inst);
InstanceHandle wd = Execute(context, ramb); InstanceHandle wd = Execute(context, ramb, inst);
string value = context.GetWorkData<string>(wd); string value = context.GetWorkData<string>(wd);
return value; return value;

View File

@ -25,8 +25,21 @@ public class OmsContext
{ {
public Oms Oms { get; } public Oms Oms { get; }
public OmsStackTrace StackTrace { get; } public OmsStackTrace StackTrace { get; }
private Stack<IInstanceReference?> TargetInstances = new Stack<IInstanceReference?>();
private Stack<Dictionary<InstanceHandle, object>> WorkDataSets = new Stack<Dictionary<InstanceHandle, object>>(); private Stack<Dictionary<InstanceHandle, object>> WorkDataSets = new Stack<Dictionary<InstanceHandle, object>>();
public IInstanceReference? TargetInstance
{
get
{
if (TargetInstances.Count > 0)
{
return TargetInstances.Peek();
}
return null;
}
}
internal OmsContext(Oms oms) internal OmsContext(Oms oms)
{ {
Oms = oms; Oms = oms;
@ -35,26 +48,47 @@ public class OmsContext
private Dictionary<InstanceHandle, object?> _WorkData = new Dictionary<InstanceHandle, object?>(); private Dictionary<InstanceHandle, object?> _WorkData = new Dictionary<InstanceHandle, object?>();
private Dictionary<InstanceHandle, object?> _GlobalData = new Dictionary<InstanceHandle, object?>(); private Dictionary<InstanceHandle, object?> _GlobalData = new Dictionary<InstanceHandle, object?>();
public object? GetWorkData(WorkSet parm) public object? GetWorkData(IInstanceReference parm)
{ {
return GetWorkData(parm.GetHandle()); if (_WorkData.ContainsKey(parm.GetHandle()))
} return _WorkData[parm.GetHandle()];
public object? GetWorkData(InstanceHandle parm)
{
if (_WorkData.ContainsKey(parm))
return _WorkData[parm];
foreach (Dictionary<InstanceHandle, object> set in WorkDataSets) foreach (Dictionary<InstanceHandle, object> set in WorkDataSets)
{ {
if (set.ContainsKey(parm)) if (set.ContainsKey(parm.GetHandle()))
return set[parm]; {
object? val = set[parm.GetHandle()];
if (val != null)
{
return val;
}
}
}
foreach (KeyValuePair<InstanceHandle, object> kvp in _WorkData)
{
if (Oms.IsSubclassOf(kvp.Key, parm.GetHandle()))
{
return kvp.Value;
}
}
foreach (Dictionary<InstanceHandle, object> set in WorkDataSets)
{
foreach (KeyValuePair<InstanceHandle, object> 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)); // Console.Error.WriteLine("work data not found for parm {0}", Oms.GetGlobalIdentifier(parm));
return null; return null;
} }
public T GetWorkData<T>(InstanceHandle parm, T defaultValue = default(T)) public T GetWorkData<T>(IInstanceReference parm, T defaultValue = default(T))
{ {
object? val = GetWorkData(parm); object? val = GetWorkData(parm);
if (val is T) if (val is T)
@ -64,7 +98,7 @@ public class OmsContext
return defaultValue; return defaultValue;
} }
public void SetWorkData(WorkSet parm, object? value) public void SetWorkData(IInstanceReference parm, object? value)
{ {
SetWorkData(parm.GetHandle(), value); SetWorkData(parm.GetHandle(), value);
} }
@ -147,10 +181,11 @@ public class OmsContext
_WorkData[parm] = value; _WorkData[parm] = value;
} }
public void Push(InstanceHandle methodOrMethodBinding) public void Push(InstanceHandle methodOrMethodBinding, IInstanceReference? targetInstance = null)
{ {
StackTrace.Push(methodOrMethodBinding); StackTrace.Push(methodOrMethodBinding);
WorkDataSets.Push(_WorkData); WorkDataSets.Push(_WorkData);
TargetInstances.Push(targetInstance);
_WorkData = new Dictionary<InstanceHandle, object?>(); _WorkData = new Dictionary<InstanceHandle, object?>();
} }
@ -158,6 +193,8 @@ public class OmsContext
{ {
InstanceHandle methodOrMethodBinding = StackTrace.Pop(); InstanceHandle methodOrMethodBinding = StackTrace.Pop();
_WorkData = WorkDataSets.Pop(); _WorkData = WorkDataSets.Pop();
TargetInstances.Pop();
return methodOrMethodBinding; return methodOrMethodBinding;
} }

View File

@ -109,6 +109,10 @@ public class OmsMethodBuilder
{ {
InstanceHandle method = Oms.CreateInstanceOf(methodClassInstance, globalIdentifier); InstanceHandle method = Oms.CreateInstanceOf(methodClassInstance, globalIdentifier);
Oms.AssignRelationship(method, Oms.GetInstance(KnownRelationshipGuids.Method__for__Class), forClassInstance); 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) if (!Oms.ValidateConstraints)
{ {
// sibling relationships aren't being generated automatically // sibling relationships aren't being generated automatically

View File

@ -22,6 +22,7 @@ namespace Mocha.Core;
public class OmsStackTrace public class OmsStackTrace
{ {
private Stack<InstanceHandle> stack = new Stack<InstanceHandle>(); private Stack<InstanceHandle> stack = new Stack<InstanceHandle>();
public int Count { get { return stack.Count; } }
private OmsContext parent; private OmsContext parent;
internal OmsStackTrace(OmsContext parent) internal OmsStackTrace(OmsContext parent)
@ -53,4 +54,14 @@ public class OmsStackTrace
} }
return sb.ToString(); return sb.ToString();
} }
public InstanceHandle Peek(int level = 0)
{
if (level == 0)
{
InstanceHandle ih = stack.Peek();
return ih;
}
return stack.ElementAt(level);
}
} }

View File

@ -42,6 +42,7 @@ public class ZqIntegrator
} }
} }
InstanceHandle a_Name = OMS.GetInstance(KnownAttributeGuids.Text.Name);
InstanceKey parentIK = OMS.GetInstanceKey(ih); InstanceKey parentIK = OMS.GetInstanceKey(ih);
foreach (ZqInstance inst in zql.Instances) foreach (ZqInstance inst in zql.Instances)
{ {
@ -51,7 +52,6 @@ public class ZqIntegrator
OMS.SetInstanceKey(ih2, inst.InstanceKey); OMS.SetInstanceKey(ih2, inst.InstanceKey);
} }
InstanceHandle a_Name = OMS.GetInstance(KnownAttributeGuids.Text.Name);
if (a_Name != InstanceHandle.Empty) if (a_Name != InstanceHandle.Empty)
{ {
if (inst.Name != null) if (inst.Name != null)
@ -65,6 +65,15 @@ public class ZqIntegrator
{ {
if (meth is ZqSimpleReturnMethod gsi) 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); Core.Oop.WorkSet ws = OMS.CreateWorkSet(meth.Name);
if (gsi.ReturnValue is ZqArray) 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) else if (gsi.ReturnValue is ZqVariableReference)
{ {
object r = ResolveVariable(ih, ((ZqVariableReference)gsi.ReturnValue).Name); object r = ResolveVariable(ih, ((ZqVariableReference)gsi.ReturnValue).Name);
if (r is InstanceHandle ihret) 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; return null;
} }
private object ResolveVariable(Class parentClassInstance, string name) public object ResolveVariable(Class parentClassInstance, string name)
{ {
InstanceHandle ihret = OMS.GetInstanceByName(parentClassInstance, name); InstanceHandle ihret = OMS.GetInstanceByName(parentClassInstance, name);
if (ihret != InstanceHandle.Empty) if (ihret != InstanceHandle.Empty)
@ -183,7 +192,7 @@ public class ZqIntegrator
throw new NotImplementedException(); throw new NotImplementedException();
} }
private string ZqNormalizeName(string fullName) public string ZqNormalizeName(string fullName)
{ {
return fullName.Replace("-", "_").Replace(" ", "").Replace("(", "_").Replace(")", "_"); return fullName.Replace("-", "_").Replace(" ", "").Replace("(", "_").Replace(")", "_");
} }

View File

@ -45,6 +45,9 @@ public abstract class ZqMethod : ZqObject, IZqMethod
public ZqMethodCall? Executable { get; internal set; } = null; public ZqMethodCall? Executable { get; internal set; } = null;
public virtual ZqDataType ReturnDataType { get; set; } public virtual ZqDataType ReturnDataType { get; set; }
public bool IsStatic { get; set; }
public ZqAccessModifier AccessModifier { get; set; }
public ZqMethod(string name) public ZqMethod(string name)
{ {
Name = name; Name = name;

View File

@ -239,7 +239,7 @@ public class ZqParser
} }
else if (tok.Equals("function")) else if (tok.Equals("function"))
{ {
return ParseFunction(text, ref i, ref parms); ZqMethod? p = ParseFunction(text, ref i, ref parms);
} }
else if (tok.Equals("}")) else if (tok.Equals("}"))
{ {
@ -251,9 +251,15 @@ public class ZqParser
return thisClass; 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) 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(); string functionName = ReadUntil(pp, ref j, '(', false).Trim();
List<ZqParameter> parmListList = new List<ZqParameter>(); List<ZqParameter> parmListList = new List<ZqParameter>();

View File

@ -184,7 +184,7 @@ public class McxMiniLibraryPlugin : LibraryPlugin
protected override void LoadInternal(string filename, Library library) 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); LoadInternal(fs, library);
} }
} }

View File

@ -48,7 +48,7 @@ public class BasicTests : OmsTestsBase
InstanceHandle irTestClass = Oms.GetInstance(TEST_CLASS_GUID); InstanceHandle irTestClass = Oms.GetInstance(TEST_CLASS_GUID);
Assert.That(irTestClass, Is.Not.EqualTo(InstanceHandle.Empty)); 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)); Assert.That(irTestAttribute, Is.Not.EqualTo(InstanceHandle.Empty));
Oms.AddAttribute(irTestClass, irTestAttribute); Oms.AddAttribute(irTestClass, irTestAttribute);

View File

@ -7,11 +7,15 @@ namespace Mocha.Core.Tests;
public class DerivedInstanceTests : OmsTestsBase public class DerivedInstanceTests : OmsTestsBase
{ {
Class TEST_CLASS_DERIVED; Class TEST_CLASS_DERIVED;
InstanceKey ik_derived;
protected override void AfterSetup() protected override void AfterSetup()
{ {
base.AfterSetup(); base.AfterSetup();
TEST_CLASS_DERIVED = Oms.CreateClass("Test Class (Derived)"); 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); Oms.SetAttributeValue(TEST_CLASS_DERIVED, Oms.GetInstance(KnownAttributeGuids.Boolean.Derived), true);
// Derived classes are represented only by InstanceKeys with the form {ClassId}!{DerivedData}, where // Derived classes are represented only by InstanceKeys with the form {ClassId}!{DerivedData}, where
@ -43,7 +47,7 @@ public class DerivedInstanceTests : OmsTestsBase
[Test] [Test]
public void Derived_Instance_Test__instance_key_Parse() 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); InstanceKey ik = InstanceKey.Parse(ikStr);
InstanceHandle ih = Oms.GetInstance(ik); InstanceHandle ih = Oms.GetInstance(ik);

View File

@ -22,6 +22,24 @@ namespace Mocha.Core.Tests.MethodTests;
public class EvaluateBooleanExpressionMethodTests : MethodTestsBase 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] [Test]
public void Test_EBE_Returns_False_if_Method_is_NOT_Get_Attribute_Method() 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); context.SetWorkData(c_Instance, Instance__get__Parent_Class);
InstanceHandle wsRet = Oms.Execute(context, 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))); Assert.That(pclass, Is.EqualTo(Oms.GetInstance(KnownInstanceGuids.MethodClasses.GetRelationshipMethod)));

View File

@ -29,7 +29,7 @@ namespace Mocha.Core.Tests.MethodTests
InstanceHandle irTestClass = Oms.GetInstance(TEST_CLASS_GUID); InstanceHandle irTestClass = Oms.GetInstance(TEST_CLASS_GUID);
InstanceHandle irTestClassInstance = Oms.CreateInstanceOf(irTestClass); 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)); Assert.That(irTestAttribute, Is.Not.EqualTo(InstanceHandle.Empty));
Oms.AddAttribute(irTestClass, irTestAttribute); Oms.AddAttribute(irTestClass, irTestAttribute);

View File

@ -112,10 +112,10 @@ public class MethodBindingTests : MethodTestsBase
WorkSet ws = Oms.CreateWorkSet("Singleton OMS"); 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); 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 rsmb2 = m2.CreateMethodBinding(Oms);
ReturnInstanceSetMethodBinding rsmb3 = m2.CreateMethodBinding(Oms); ReturnInstanceSetMethodBinding rsmb3 = m2.CreateMethodBinding(Oms);

View File

@ -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__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_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__has_multiple__Test_Class_2 = new Guid("{4c51e214-68c8-4e14-8e94-4e4667f05778}");
Guid gid_r_Test_Class_2__multiple_for__Test_Class = new Guid("{2864dfd9-0313-4801-96bf-b9be99ea172d}"); Guid gid_r_Test_Class_2__multiple_for__Test_Class = new Guid("{fcf70fa7-ebd0-438a-a534-ee31dbe3b04f}");
protected Class c_TestClass, c_TestClass2; protected Class c_TestClass, c_TestClass2;
protected Relationship r_Test_Class__has__Test_Class_2, r_Test_Class_2__for__Test_Class; protected Relationship r_Test_Class__has__Test_Class_2, r_Test_Class_2__for__Test_Class;

View File

@ -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<Class>(TEST_CLASS_GUID);
Class c_TestClass2 = Oms.GetInstance<Class>(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<string>(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<Class>(TEST_CLASS_GUID);
Class c_TestClass2 = Oms.GetInstance<Class>(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<string>(context, ramb1);
Assert.That(value, Is.EqualTo("Test Text 1"));
}, Throws.InstanceOf<MethodAccessException>());
}
[Test]
public void Private_Static_Method_Called_From_Another_Class_Fails()
{
Class c_TestClass = Oms.GetInstance<Class>(TEST_CLASS_GUID);
Class c_TestClass2 = Oms.GetInstance<Class>(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<string>(context, ramb1);
Assert.That(value, Is.EqualTo("Test Text 1"));
}, Throws.InstanceOf<MethodAccessException>());
}
}

View File

@ -37,8 +37,9 @@ public class RelationshipTests : OmsTestsBase
{ {
InstanceHandle c_Class = Oms.GetInstance(KnownInstanceGuids.Classes.Class); InstanceHandle c_Class = Oms.GetInstance(KnownInstanceGuids.Classes.Class);
c_TestClass = Oms.CreateClass("Test Class", TEST_CLASS_GUID); c_TestClass = Oms.GetInstance<Class>(TEST_CLASS_GUID);
c_TestClass2 = Oms.CreateClass("Test Class 2", TEST_CLASS2_GUID); c_TestClass2 = Oms.GetInstance<Class>(TEST_CLASS2_GUID);
c_TestClassInstance = Oms.CreateInstanceOf(c_TestClass); c_TestClassInstance = Oms.CreateInstanceOf(c_TestClass);
c_TestClass2Instance1 = Oms.CreateInstanceOf(c_TestClass2); c_TestClass2Instance1 = Oms.CreateInstanceOf(c_TestClass2);

View File

@ -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);
}
}

View File

@ -0,0 +1 @@
global using NUnit.Framework;

View File

@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="NUnit.Analyzers" Version="3.6.1" />
<PackageReference Include="coverlet.collector" Version="6.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../../../framework-dotnet/framework-dotnet/src/lib/MBS.Core/MBS.Core.csproj" />
<ProjectReference Include="../../src/app/Mocha.Oms.Server/Mocha.Oms.Server.csproj" />
<ProjectReference Include="../../src/lib/Mocha.Core.UI.Server/Mocha.Core.UI.Server.csproj" />
<ProjectReference Include="../../src/lib/Mocha.Core/Mocha.Core.csproj" />
</ItemGroup>
</Project>

@ -1 +1 @@
Subproject commit e6b974f6514320f43228da2abdcd0ce66b3c30c1 Subproject commit 19d487683468db5b7e34d449ac105b088cef9b5a