diff --git a/SysML2.NET.Tests/Extend/ActorMembershipExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/ActorMembershipExtensionsTestFixture.cs
index 2ad5978dd..b5f0959e0 100644
--- a/SysML2.NET.Tests/Extend/ActorMembershipExtensionsTestFixture.cs
+++ b/SysML2.NET.Tests/Extend/ActorMembershipExtensionsTestFixture.cs
@@ -1,38 +1,84 @@
-// -------------------------------------------------------------------------------------------------
+// -------------------------------------------------------------------------------------------------
//
-//
+//
// Copyright 2022-2026 Starion Group S.A.
-//
+//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
-//
+//
// http://www.apache.org/licenses/LICENSE-2.0
-//
+//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-//
+//
//
// ------------------------------------------------------------------------------------------------
namespace SysML2.NET.Tests.Extend
{
using System;
-
+
using NUnit.Framework;
-
+
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Core.POCO.Root.Namespaces;
+ using SysML2.NET.Core.POCO.Systems.Parts;
using SysML2.NET.Core.POCO.Systems.Requirements;
+ using SysML2.NET.Exceptions;
+ using SysML2.NET.Extensions;
[TestFixture]
public class ActorMembershipExtensionsTestFixture
{
[Test]
- public void ComputeOwnedActorParameter_ThrowsNotSupportedException()
+ public void VerifyComputeOwnedActorParameter()
{
- Assert.That(() => ((IActorMembership)null).ComputeOwnedActorParameter(), Throws.TypeOf());
+ Assert.That(() => ((IActorMembership)null).ComputeOwnedActorParameter(), Throws.TypeOf());
+
+ // Empty OwnedRelatedElement → [1..1] violation: throws IncompleteModelException.
+ var emptyMembership = new ActorMembership();
+
+ Assert.That(() => emptyMembership.ComputeOwnedActorParameter(), Throws.TypeOf());
+
+ // Single non-IPartUsage in OwnedRelatedElement → [1..1] violation: throws IncompleteModelException.
+ var nonPartMembership = new ActorMembership();
+ var nonPartElement = new Namespace();
+ ((IContainedRelationship)nonPartMembership).OwnedRelatedElement.Add(nonPartElement);
+
+ Assert.That(() => nonPartMembership.ComputeOwnedActorParameter(), Throws.TypeOf());
+
+ // Single IPartUsage wired via the public API → returned.
+ // ActorMembership is a FeatureMembership and requires an IType source per AssignOwnership;
+ // RequirementDefinition is the natural Requirements-namespace IType for an actor parameter.
+ var owningDefinition = new RequirementDefinition();
+ var actorMembership = new ActorMembership();
+ var partUsage = new PartUsage();
+ owningDefinition.AssignOwnership(actorMembership, partUsage);
+
+ Assert.That(actorMembership.ComputeOwnedActorParameter(), Is.SameAs(partUsage));
+
+ // Two IPartUsage in OwnedRelatedElement → [1..1] violation: throws IncompleteModelException.
+ var twoPartMembership = new ActorMembership();
+ var firstPart = new PartUsage();
+ var secondPart = new PartUsage();
+ ((IContainedRelationship)twoPartMembership).OwnedRelatedElement.Add(firstPart);
+ ((IContainedRelationship)twoPartMembership).OwnedRelatedElement.Add(secondPart);
+
+ Assert.That(() => twoPartMembership.ComputeOwnedActorParameter(), Throws.TypeOf());
+
+ // Mixed: non-IPartUsage (Namespace) alongside a single IPartUsage — the type filter picks
+ // out the PartUsage regardless of its position.
+ var mixedMembership = new ActorMembership();
+ var siblingNamespace = new Namespace();
+ var mixedPart = new PartUsage();
+ ((IContainedRelationship)mixedMembership).OwnedRelatedElement.Add(siblingNamespace);
+ ((IContainedRelationship)mixedMembership).OwnedRelatedElement.Add(mixedPart);
+
+ Assert.That(mixedMembership.ComputeOwnedActorParameter(), Is.SameAs(mixedPart));
}
}
}
diff --git a/SysML2.NET.Tests/Extend/AssertConstraintUsageExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/AssertConstraintUsageExtensionsTestFixture.cs
index 3c4410d56..fe7ee0764 100644
--- a/SysML2.NET.Tests/Extend/AssertConstraintUsageExtensionsTestFixture.cs
+++ b/SysML2.NET.Tests/Extend/AssertConstraintUsageExtensionsTestFixture.cs
@@ -1,38 +1,65 @@
-// -------------------------------------------------------------------------------------------------
+// -------------------------------------------------------------------------------------------------
//
-//
+//
// Copyright 2022-2026 Starion Group S.A.
-//
+//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
-//
+//
// http://www.apache.org/licenses/LICENSE-2.0
-//
+//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-//
+//
//
// ------------------------------------------------------------------------------------------------
namespace SysML2.NET.Tests.Extend
{
using System;
-
+
using NUnit.Framework;
- using SysML2.NET.Core.POCO.Systems.Constraints ;
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Systems.Constraints;
+ using SysML2.NET.Core.POCO.Systems.Parts;
+ using SysML2.NET.Extensions;
[TestFixture]
public class AssertConstraintUsageExtensionsTestFixture
{
[Test]
- public void ComputeAssertedConstraint_ThrowsNotSupportedException()
+ public void VerifyComputeAssertedConstraint()
{
- Assert.That(() => ((IAssertConstraintUsage)null).ComputeAssertedConstraint(), Throws.TypeOf());
+ Assert.That(() => ((IAssertConstraintUsage)null).ComputeAssertedConstraint(), Throws.TypeOf());
+
+ // No ownedReferenceSubsetting → ReferencedFeatureTarget() returns null →
+ // self-fallback branch: returns the subject itself (which IS-A IConstraintUsage).
+ var selfFallbackUsage = new AssertConstraintUsage();
+
+ Assert.That(selfFallbackUsage.ComputeAssertedConstraint(), Is.SameAs(selfFallbackUsage));
+
+ // ownedReferenceSubsetting points to a ConstraintUsage → that ConstraintUsage is returned
+ // (since the referenced feature's featureTarget is itself when it has no chainingFeatures).
+ var withConstraintRefUsage = new AssertConstraintUsage();
+ var targetConstraint = new ConstraintUsage();
+ var referenceSubsetting = new ReferenceSubsetting { ReferencedFeature = targetConstraint };
+ withConstraintRefUsage.AssignOwnership(referenceSubsetting);
+
+ Assert.That(withConstraintRefUsage.ComputeAssertedConstraint(), Is.SameAs(targetConstraint));
+
+ // ownedReferenceSubsetting points to a non-ConstraintUsage feature → the "as IConstraintUsage"
+ // cast yields null (the OCL "else null" branch).
+ var withNonConstraintRefUsage = new AssertConstraintUsage();
+ var nonConstraintTarget = new PartUsage();
+ var nonConstraintRefSubsetting = new ReferenceSubsetting { ReferencedFeature = nonConstraintTarget };
+ withNonConstraintRefUsage.AssignOwnership(nonConstraintRefSubsetting);
+
+ Assert.That(withNonConstraintRefUsage.ComputeAssertedConstraint(), Is.Null);
}
}
}
diff --git a/SysML2.NET.Tests/Extend/CaseDefinitionExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/CaseDefinitionExtensionsTestFixture.cs
index 5745038d8..27f73238c 100644
--- a/SysML2.NET.Tests/Extend/CaseDefinitionExtensionsTestFixture.cs
+++ b/SysML2.NET.Tests/Extend/CaseDefinitionExtensionsTestFixture.cs
@@ -50,12 +50,12 @@ public void VerifyComputeActorParameter()
Assert.That(caseDefinition.ComputeActorParameter(), Is.Empty);
- // For Later: populated case depends on IActorMembership.ComputeOwnedActorParameter, which is still a stub.
+ // Populated: an ActorMembership carrying a PartUsage → that PartUsage appears in the result.
var actorMembership = new ActorMembership();
var actorPartUsage = new PartUsage();
caseDefinition.AssignOwnership(actorMembership, actorPartUsage);
- Assert.That(() => caseDefinition.ComputeActorParameter(), Throws.TypeOf());
+ Assert.That(caseDefinition.ComputeActorParameter(), Is.EqualTo([actorPartUsage]));
}
[Test]
diff --git a/SysML2.NET.Tests/Extend/CaseUsageExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/CaseUsageExtensionsTestFixture.cs
index 7cf27a63e..4b2e31a13 100644
--- a/SysML2.NET.Tests/Extend/CaseUsageExtensionsTestFixture.cs
+++ b/SysML2.NET.Tests/Extend/CaseUsageExtensionsTestFixture.cs
@@ -51,12 +51,12 @@ public void VerifyComputeActorParameter()
Assert.That(caseUsage.ComputeActorParameter(), Is.Empty);
- // For Later: populated case depends on IActorMembership.ComputeOwnedActorParameter, which is still a stub.
+ // Populated: an ActorMembership carrying a PartUsage → that PartUsage appears in the result.
var actorMembership = new ActorMembership();
var actorPartUsage = new PartUsage();
caseUsage.AssignOwnership(actorMembership, actorPartUsage);
- Assert.That(() => caseUsage.ComputeActorParameter(), Throws.TypeOf());
+ Assert.That(caseUsage.ComputeActorParameter(), Is.EqualTo([actorPartUsage]));
}
[Test]
diff --git a/SysML2.NET.Tests/Extend/ConstraintUsageExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/ConstraintUsageExtensionsTestFixture.cs
index 1495397c7..602d41f0a 100644
--- a/SysML2.NET.Tests/Extend/ConstraintUsageExtensionsTestFixture.cs
+++ b/SysML2.NET.Tests/Extend/ConstraintUsageExtensionsTestFixture.cs
@@ -1,38 +1,123 @@
-// -------------------------------------------------------------------------------------------------
+// -------------------------------------------------------------------------------------------------
//
-//
+//
// Copyright 2022-2026 Starion Group S.A.
-//
+//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
-//
+//
// http://www.apache.org/licenses/LICENSE-2.0
-//
+//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-//
+//
//
// ------------------------------------------------------------------------------------------------
namespace SysML2.NET.Tests.Extend
{
using System;
-
+
using NUnit.Framework;
-
+
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Kernel.Functions;
using SysML2.NET.Core.POCO.Systems.Constraints;
+ using SysML2.NET.Core.POCO.Systems.Parts;
+ using SysML2.NET.Core.POCO.Systems.Requirements;
+ using SysML2.NET.Extensions;
[TestFixture]
public class ConstraintUsageExtensionsTestFixture
{
[Test]
- public void ComputeConstraintDefinition_ThrowsNotSupportedException()
+ public void VerifyComputeConstraintDefinition()
+ {
+ Assert.That(() => ((IConstraintUsage)null).ComputeConstraintDefinition(), Throws.TypeOf());
+
+ // Empty OwnedRelationship → no FeatureTyping → null.
+ var emptyUsage = new ConstraintUsage();
+
+ Assert.That(emptyUsage.ComputeConstraintDefinition(), Is.Null);
+
+ // FeatureTyping whose Type is a non-Predicate → returns null (no IPredicate match).
+ var nonPredicateUsage = new ConstraintUsage();
+ var partDefinition = new PartDefinition();
+ var nonPredicateTyping = new FeatureTyping { Type = partDefinition };
+ nonPredicateUsage.AssignOwnership(nonPredicateTyping);
+
+ Assert.That(nonPredicateUsage.ComputeConstraintDefinition(), Is.Null);
+
+ // FeatureTyping whose Type is a Predicate → returns it.
+ var predicateUsage = new ConstraintUsage();
+ var predicate = new Predicate();
+ var predicateTyping = new FeatureTyping { Type = predicate };
+ predicateUsage.AssignOwnership(predicateTyping);
+
+ Assert.That(predicateUsage.ComputeConstraintDefinition(), Is.SameAs(predicate));
+
+ // FeatureTyping whose Type is a ConstraintDefinition (which IS-A Predicate) → returns it.
+ var constraintDefUsage = new ConstraintUsage();
+ var constraintDefinition = new ConstraintDefinition();
+ var constraintDefTyping = new FeatureTyping { Type = constraintDefinition };
+ constraintDefUsage.AssignOwnership(constraintDefTyping);
+
+ Assert.That(constraintDefUsage.ComputeConstraintDefinition(), Is.SameAs(constraintDefinition));
+ }
+
+ [Test]
+ public void VerifyComputeRedefinedNamingFeatureOperation()
{
- Assert.That(() => ((IConstraintUsage)null).ComputeConstraintDefinition(), Throws.TypeOf());
+ Assert.That(() => ((IConstraintUsage)null).ComputeRedefinedNamingFeatureOperation(), Throws.TypeOf());
+
+ // No owningFeatureMembership → else branch delegates to UsageExtensions.ComputeRedefinedNamingFeatureOperation.
+ // With no OwnedRelationship (no Redefinition) and not a VariantMembership → null.
+ var elseFallbackUsage = new ConstraintUsage();
+
+ Assert.That(elseFallbackUsage.ComputeRedefinedNamingFeatureOperation(), Is.Null);
+
+ // owningFeatureMembership IS a RequirementConstraintMembership AND ownedReferenceSubsetting present →
+ // returns ownedReferenceSubsetting.ReferencedFeature.featureTarget (which is itself for a feature
+ // with no chainingFeatures).
+ var owningRequirementUsage = new RequirementUsage();
+ var requirementConstraintMembership = new RequirementConstraintMembership();
+ var usageInBranch1 = new ConstraintUsage();
+ owningRequirementUsage.AssignOwnership(requirementConstraintMembership, usageInBranch1);
+
+ var refTarget = new Feature();
+ var referenceSubsetting = new ReferenceSubsetting { ReferencedFeature = refTarget };
+ usageInBranch1.AssignOwnership(referenceSubsetting);
+
+ Assert.That(usageInBranch1.ComputeRedefinedNamingFeatureOperation(), Is.SameAs(refTarget));
+
+ // owningFeatureMembership is RequirementConstraintMembership but NO ownedReferenceSubsetting →
+ // condition fails → else branch → returns null (no Redefinition).
+ var owningRequirementUsage2 = new RequirementUsage();
+ var rcmNoRef = new RequirementConstraintMembership();
+ var usageNoRef = new ConstraintUsage();
+ owningRequirementUsage2.AssignOwnership(rcmNoRef, usageNoRef);
+
+ Assert.That(usageNoRef.ComputeRedefinedNamingFeatureOperation(), Is.Null);
+ }
+
+ [Test]
+ public void VerifyComputeRedefinedModelLevelEvaluableOperation()
+ {
+ Assert.That(() => ((IConstraintUsage)null).ComputeRedefinedModelLevelEvaluableOperation([]), Throws.TypeOf());
+
+ // OCL body is literally `false` — independent of subject state and of the visited list.
+ var usage = new ConstraintUsage();
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(usage.ComputeRedefinedModelLevelEvaluableOperation([]), Is.False);
+ Assert.That(usage.ComputeRedefinedModelLevelEvaluableOperation(null), Is.False);
+ Assert.That(usage.ComputeRedefinedModelLevelEvaluableOperation([new Feature()]), Is.False);
+ }
}
}
}
diff --git a/SysML2.NET.Tests/Extend/FramedConcernMembershipExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/FramedConcernMembershipExtensionsTestFixture.cs
index 8adb5ec7d..015f451e1 100644
--- a/SysML2.NET.Tests/Extend/FramedConcernMembershipExtensionsTestFixture.cs
+++ b/SysML2.NET.Tests/Extend/FramedConcernMembershipExtensionsTestFixture.cs
@@ -1,43 +1,135 @@
-// -------------------------------------------------------------------------------------------------
+// -------------------------------------------------------------------------------------------------
//
-//
+//
// Copyright 2022-2026 Starion Group S.A.
-//
+//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
-//
+//
// http://www.apache.org/licenses/LICENSE-2.0
-//
+//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-//
+//
//
// ------------------------------------------------------------------------------------------------
namespace SysML2.NET.Tests.Extend
{
using System;
-
+
using NUnit.Framework;
-
+
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Core.POCO.Root.Namespaces;
+ using SysML2.NET.Core.POCO.Systems.Parts;
using SysML2.NET.Core.POCO.Systems.Requirements;
+ using SysML2.NET.Exceptions;
+ using SysML2.NET.Extensions;
[TestFixture]
public class FramedConcernMembershipExtensionsTestFixture
{
[Test]
- public void ComputeOwnedConcern_ThrowsNotSupportedException()
+ public void VerifyComputeOwnedConcern()
{
- Assert.That(() => ((IFramedConcernMembership)null).ComputeOwnedConcern(), Throws.TypeOf());
+ Assert.That(() => ((IFramedConcernMembership)null).ComputeOwnedConcern(), Throws.TypeOf());
+
+ // Empty OwnedRelatedElement → [1..1] violation: throws IncompleteModelException.
+ var emptyMembership = new FramedConcernMembership();
+
+ Assert.That(() => emptyMembership.ComputeOwnedConcern(), Throws.TypeOf());
+
+ // Single non-IConcernUsage in OwnedRelatedElement → [1..1] violation: throws IncompleteModelException.
+ var nonConcernMembership = new FramedConcernMembership();
+ var nonConcernElement = new Namespace();
+ ((IContainedRelationship)nonConcernMembership).OwnedRelatedElement.Add(nonConcernElement);
+
+ Assert.That(() => nonConcernMembership.ComputeOwnedConcern(), Throws.TypeOf());
+
+ // Single IConcernUsage wired via the public API → returned.
+ // FramedConcernMembership is a FeatureMembership and requires an IType source per
+ // AssignOwnership; RequirementDefinition is the natural Requirements-namespace IType
+ // for a framed concern.
+ var owningNamespace = new RequirementDefinition();
+ var framedMembership = new FramedConcernMembership();
+ var concernUsage = new ConcernUsage();
+ owningNamespace.AssignOwnership(framedMembership, concernUsage);
+
+ Assert.That(framedMembership.ComputeOwnedConcern(), Is.SameAs(concernUsage));
+
+ // Two IConcernUsage in OwnedRelatedElement → [1..1] violation: throws IncompleteModelException.
+ var twoConcernMembership = new FramedConcernMembership();
+ var firstConcern = new ConcernUsage();
+ var secondConcern = new ConcernUsage();
+ ((IContainedRelationship)twoConcernMembership).OwnedRelatedElement.Add(firstConcern);
+ ((IContainedRelationship)twoConcernMembership).OwnedRelatedElement.Add(secondConcern);
+
+ Assert.That(() => twoConcernMembership.ComputeOwnedConcern(), Throws.TypeOf());
+
+ // Mixed: non-IConcernUsage (Namespace) alongside a single IConcernUsage — the type filter
+ // picks out the ConcernUsage regardless of its position.
+ var mixedMembership = new FramedConcernMembership();
+ var siblingNamespace = new Namespace();
+ var mixedConcern = new ConcernUsage();
+ ((IContainedRelationship)mixedMembership).OwnedRelatedElement.Add(siblingNamespace);
+ ((IContainedRelationship)mixedMembership).OwnedRelatedElement.Add(mixedConcern);
+
+ Assert.That(mixedMembership.ComputeOwnedConcern(), Is.SameAs(mixedConcern));
}
+
[Test]
- public void ComputeReferencedConcern_ThrowsNotSupportedException()
+ public void VerifyComputeReferencedConcern()
{
- Assert.That(() => ((IFramedConcernMembership)null).ComputeReferencedConcern(), Throws.TypeOf());
+ Assert.That(() => ((IFramedConcernMembership)null).ComputeReferencedConcern(), Throws.TypeOf());
+
+ // Empty ownedConcern → propagates IncompleteModelException from ownedConcern's [1..1] guard.
+ var emptyMembership = new FramedConcernMembership();
+
+ Assert.That(() => emptyMembership.ComputeReferencedConcern(), Throws.TypeOf());
+
+ // Populated, no ownedReferenceSubsetting on the ownedConcern → referencedFeatureTarget is null
+ // → returns ownedConcern itself.
+ // FramedConcernMembership is a FeatureMembership and requires an IType source per
+ // AssignOwnership; RequirementDefinition is the natural Requirements-namespace IType
+ // for a framed concern.
+ var owningNamespace = new RequirementDefinition();
+ var membership = new FramedConcernMembership();
+ var ownedConcern = new ConcernUsage();
+ owningNamespace.AssignOwnership(membership, ownedConcern);
+
+ Assert.That(membership.ComputeReferencedConcern(), Is.SameAs(ownedConcern));
+
+ // Populated, with ownedReferenceSubsetting whose ReferencedFeature is itself a ConcernUsage
+ // → returns that ConcernUsage.
+ var owningNamespace2 = new RequirementDefinition();
+ var membership2 = new FramedConcernMembership();
+ var ownedConcern2 = new ConcernUsage();
+ owningNamespace2.AssignOwnership(membership2, ownedConcern2);
+
+ var referencedConcern = new ConcernUsage();
+ var refSubsetting = new ReferenceSubsetting { ReferencedFeature = referencedConcern };
+ ownedConcern2.AssignOwnership(refSubsetting);
+
+ Assert.That(membership2.ComputeReferencedConcern(), Is.SameAs(referencedConcern));
+
+ // Populated, with ownedReferenceSubsetting whose ReferencedFeature is a non-ConcernUsage Feature
+ // → returns null (the OCL "else null" branch).
+ var owningNamespace3 = new RequirementDefinition();
+ var membership3 = new FramedConcernMembership();
+ var ownedConcern3 = new ConcernUsage();
+ owningNamespace3.AssignOwnership(membership3, ownedConcern3);
+
+ var nonConcernTarget = new PartUsage();
+ var refSubsetting3 = new ReferenceSubsetting { ReferencedFeature = nonConcernTarget };
+ ownedConcern3.AssignOwnership(refSubsetting3);
+
+ Assert.That(membership3.ComputeReferencedConcern(), Is.Null);
}
}
}
diff --git a/SysML2.NET.Tests/Extend/RequirementDefinitionExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/RequirementDefinitionExtensionsTestFixture.cs
index 216eeefda..87548c26c 100644
--- a/SysML2.NET.Tests/Extend/RequirementDefinitionExtensionsTestFixture.cs
+++ b/SysML2.NET.Tests/Extend/RequirementDefinitionExtensionsTestFixture.cs
@@ -56,13 +56,12 @@ public void VerifyComputeActorParameter()
Assert.That(requirementDefinition.ComputeActorParameter(), Is.Empty);
- // Populated case: ActorMembership is present; selecting ownedActorParameter triggers an
- // upstream stub (ActorMembershipExtensions.ComputeOwnedActorParameter is not yet implemented).
+ // Populated: an ActorMembership carrying a PartUsage → that PartUsage appears in the result.
var actorMembership = new ActorMembership();
var actorPartUsage = new PartUsage();
requirementDefinition.AssignOwnership(actorMembership, actorPartUsage);
- Assert.That(() => requirementDefinition.ComputeActorParameter(), Throws.TypeOf());
+ Assert.That(requirementDefinition.ComputeActorParameter(), Is.EqualTo([actorPartUsage]));
}
[Test]
@@ -113,13 +112,12 @@ public void VerifyComputeFramedConcern()
// NotSupportedException — identical to the populated stub-blocker case below.
// The discrimination block is omitted until upstream stubs are implemented.
- // Populated case: FramedConcernMembership is present; selecting ownedConcern triggers an
- // upstream stub (FramedConcernMembershipExtensions.ComputeOwnedConcern is not yet implemented).
+ // Populated: a FramedConcernMembership carrying a ConcernUsage → that ConcernUsage appears in the result.
var framedMembership = new FramedConcernMembership();
var concernUsage = new ConcernUsage();
requirementDefinition.AssignOwnership(framedMembership, concernUsage);
- Assert.That(() => requirementDefinition.ComputeFramedConcern(), Throws.TypeOf());
+ Assert.That(requirementDefinition.ComputeFramedConcern(), Is.EqualTo([concernUsage]));
}
[Test]
diff --git a/SysML2.NET.Tests/Extend/RequirementUsageExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/RequirementUsageExtensionsTestFixture.cs
index 6ecc53d4f..60f858235 100644
--- a/SysML2.NET.Tests/Extend/RequirementUsageExtensionsTestFixture.cs
+++ b/SysML2.NET.Tests/Extend/RequirementUsageExtensionsTestFixture.cs
@@ -57,13 +57,12 @@ public void VerifyComputeActorParameter()
Assert.That(requirementUsage.ComputeActorParameter(), Is.Empty);
- // Populated case: ActorMembership is present; selecting ownedActorParameter triggers an
- // upstream stub (ActorMembershipExtensions.ComputeOwnedActorParameter is not yet implemented).
+ // Populated: an ActorMembership carrying a PartUsage → that PartUsage appears in the result.
var actorMembership = new ActorMembership();
var actorPartUsage = new PartUsage();
requirementUsage.AssignOwnership(actorMembership, actorPartUsage);
- Assert.That(() => requirementUsage.ComputeActorParameter(), Throws.TypeOf());
+ Assert.That(requirementUsage.ComputeActorParameter(), Is.EqualTo([actorPartUsage]));
}
[Test]
@@ -114,13 +113,12 @@ public void VerifyComputeFramedConcern()
// NotSupportedException — identical to the populated stub-blocker case below.
// The discrimination block is omitted until upstream stubs are implemented.
- // Populated case: FramedConcernMembership is present; selecting ownedConcern triggers an
- // upstream stub (FramedConcernMembershipExtensions.ComputeOwnedConcern is not yet implemented).
+ // Populated: a FramedConcernMembership carrying a ConcernUsage → that ConcernUsage appears in the result.
var framedMembership = new FramedConcernMembership();
var concernUsage = new ConcernUsage();
requirementUsage.AssignOwnership(framedMembership, concernUsage);
- Assert.That(() => requirementUsage.ComputeFramedConcern(), Throws.TypeOf());
+ Assert.That(requirementUsage.ComputeFramedConcern(), Is.EqualTo([concernUsage]));
}
[Test]
diff --git a/SysML2.NET.Tests/Extend/RequirementVerificationMembershipExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/RequirementVerificationMembershipExtensionsTestFixture.cs
index b691b212b..19d5138e9 100644
--- a/SysML2.NET.Tests/Extend/RequirementVerificationMembershipExtensionsTestFixture.cs
+++ b/SysML2.NET.Tests/Extend/RequirementVerificationMembershipExtensionsTestFixture.cs
@@ -1,44 +1,136 @@
-// -------------------------------------------------------------------------------------------------
+// -------------------------------------------------------------------------------------------------
//
-//
+//
// Copyright 2022-2026 Starion Group S.A.
-//
+//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
-//
+//
// http://www.apache.org/licenses/LICENSE-2.0
-//
+//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-//
+//
//
// ------------------------------------------------------------------------------------------------
namespace SysML2.NET.Tests.Extend
{
using System;
-
+
using NUnit.Framework;
-
+
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Root.Elements;
+ using SysML2.NET.Core.POCO.Root.Namespaces;
+ using SysML2.NET.Core.POCO.Systems.Parts;
+ using SysML2.NET.Core.POCO.Systems.Requirements;
using SysML2.NET.Core.POCO.Systems.VerificationCases;
+ using SysML2.NET.Exceptions;
+ using SysML2.NET.Extensions;
[TestFixture]
public class RequirementVerificationMembershipExtensionsTestFixture
{
[Test]
- public void ComputeOwnedRequirement_ThrowsNotSupportedException()
+ public void VerifyComputeOwnedRequirement()
{
- Assert.That(() => ((IRequirementVerificationMembership)null).ComputeOwnedRequirement(), Throws.TypeOf());
+ Assert.That(() => ((IRequirementVerificationMembership)null).ComputeOwnedRequirement(), Throws.TypeOf());
+
+ // Empty OwnedRelatedElement → [1..1] violation: throws IncompleteModelException.
+ var emptyMembership = new RequirementVerificationMembership();
+
+ Assert.That(() => emptyMembership.ComputeOwnedRequirement(), Throws.TypeOf());
+
+ // Single non-IRequirementUsage in OwnedRelatedElement → [1..1] violation: throws IncompleteModelException.
+ var nonRequirementMembership = new RequirementVerificationMembership();
+ var nonRequirementElement = new Namespace();
+ ((IContainedRelationship)nonRequirementMembership).OwnedRelatedElement.Add(nonRequirementElement);
+
+ Assert.That(() => nonRequirementMembership.ComputeOwnedRequirement(), Throws.TypeOf());
+
+ // Single IRequirementUsage wired via the public API → returned.
+ // RequirementVerificationMembership is a FeatureMembership (via RequirementConstraintMembership)
+ // and requires an IType source per AssignOwnership; VerificationCaseDefinition is the natural
+ // IType context for verifying a requirement.
+ var owningNamespace = new VerificationCaseDefinition();
+ var membership = new RequirementVerificationMembership();
+ var requirementUsage = new RequirementUsage();
+ owningNamespace.AssignOwnership(membership, requirementUsage);
+
+ Assert.That(membership.ComputeOwnedRequirement(), Is.SameAs(requirementUsage));
+
+ // Two IRequirementUsage in OwnedRelatedElement → [1..1] violation: throws IncompleteModelException.
+ var twoRequirementMembership = new RequirementVerificationMembership();
+ var firstReq = new RequirementUsage();
+ var secondReq = new RequirementUsage();
+ ((IContainedRelationship)twoRequirementMembership).OwnedRelatedElement.Add(firstReq);
+ ((IContainedRelationship)twoRequirementMembership).OwnedRelatedElement.Add(secondReq);
+
+ Assert.That(() => twoRequirementMembership.ComputeOwnedRequirement(), Throws.TypeOf());
+
+ // Mixed: non-IRequirementUsage (Namespace) alongside a single IRequirementUsage —
+ // the type filter picks out the RequirementUsage regardless of its position.
+ var mixedMembership = new RequirementVerificationMembership();
+ var siblingNamespace = new Namespace();
+ var mixedReq = new RequirementUsage();
+ ((IContainedRelationship)mixedMembership).OwnedRelatedElement.Add(siblingNamespace);
+ ((IContainedRelationship)mixedMembership).OwnedRelatedElement.Add(mixedReq);
+
+ Assert.That(mixedMembership.ComputeOwnedRequirement(), Is.SameAs(mixedReq));
}
-
+
[Test]
- public void ComputeVerifiedRequirement_ThrowsNotSupportedException()
+ public void VerifyComputeVerifiedRequirement()
{
- Assert.That(() => ((IRequirementVerificationMembership)null).ComputeVerifiedRequirement(), Throws.TypeOf());
+ Assert.That(() => ((IRequirementVerificationMembership)null).ComputeVerifiedRequirement(), Throws.TypeOf());
+
+ // Empty ownedRequirement → propagates IncompleteModelException from ownedRequirement's [1..1] guard.
+ var emptyMembership = new RequirementVerificationMembership();
+
+ Assert.That(() => emptyMembership.ComputeVerifiedRequirement(), Throws.TypeOf());
+
+ // Populated, no ownedReferenceSubsetting on the ownedRequirement → referencedFeatureTarget is null
+ // → returns ownedRequirement itself.
+ // RequirementVerificationMembership is a FeatureMembership (via RequirementConstraintMembership)
+ // and requires an IType source per AssignOwnership; VerificationCaseDefinition is the natural
+ // IType context for verifying a requirement.
+ var owningNamespace = new VerificationCaseDefinition();
+ var membership = new RequirementVerificationMembership();
+ var ownedRequirement = new RequirementUsage();
+ owningNamespace.AssignOwnership(membership, ownedRequirement);
+
+ Assert.That(membership.ComputeVerifiedRequirement(), Is.SameAs(ownedRequirement));
+
+ // Populated, with ownedReferenceSubsetting whose ReferencedFeature is itself a RequirementUsage
+ // → returns that RequirementUsage.
+ var owningNamespace2 = new VerificationCaseDefinition();
+ var membership2 = new RequirementVerificationMembership();
+ var ownedRequirement2 = new RequirementUsage();
+ owningNamespace2.AssignOwnership(membership2, ownedRequirement2);
+
+ var referencedRequirement = new RequirementUsage();
+ var refSubsetting = new ReferenceSubsetting { ReferencedFeature = referencedRequirement };
+ ownedRequirement2.AssignOwnership(refSubsetting);
+
+ Assert.That(membership2.ComputeVerifiedRequirement(), Is.SameAs(referencedRequirement));
+
+ // Populated, with ownedReferenceSubsetting whose ReferencedFeature is a non-RequirementUsage Feature
+ // → returns null (the OCL "else null" branch).
+ var owningNamespace3 = new VerificationCaseDefinition();
+ var membership3 = new RequirementVerificationMembership();
+ var ownedRequirement3 = new RequirementUsage();
+ owningNamespace3.AssignOwnership(membership3, ownedRequirement3);
+
+ var nonRequirementTarget = new PartUsage();
+ var refSubsetting3 = new ReferenceSubsetting { ReferencedFeature = nonRequirementTarget };
+ ownedRequirement3.AssignOwnership(refSubsetting3);
+
+ Assert.That(membership3.ComputeVerifiedRequirement(), Is.Null);
}
}
}
diff --git a/SysML2.NET.Tests/Extend/SatisfyRequirementUsageExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/SatisfyRequirementUsageExtensionsTestFixture.cs
index 506fc4b3e..a234761c4 100644
--- a/SysML2.NET.Tests/Extend/SatisfyRequirementUsageExtensionsTestFixture.cs
+++ b/SysML2.NET.Tests/Extend/SatisfyRequirementUsageExtensionsTestFixture.cs
@@ -1,43 +1,126 @@
// -------------------------------------------------------------------------------------------------
//
-//
+//
// Copyright 2022-2026 Starion Group S.A.
-//
+//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
-//
+//
// http://www.apache.org/licenses/LICENSE-2.0
-//
+//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-//
+//
//
// ------------------------------------------------------------------------------------------------
namespace SysML2.NET.Tests.Extend
{
using System;
-
+
using NUnit.Framework;
-
+
+ using SysML2.NET.Core.POCO.Core.Features;
+ using SysML2.NET.Core.POCO.Core.Types;
+ using SysML2.NET.Core.POCO.Kernel.Connectors;
+ using SysML2.NET.Core.POCO.Systems.Constraints;
+ using SysML2.NET.Core.POCO.Systems.DefinitionAndUsage;
using SysML2.NET.Core.POCO.Systems.Requirements;
+ using SysML2.NET.Extensions;
[TestFixture]
public class SatisfyRequirementUsageExtensionsTestFixture
{
[Test]
- public void ComputeSatisfiedRequirement_ThrowsNotSupportedException()
+ public void VerifyComputeSatisfiedRequirement()
{
- Assert.That(() => ((ISatisfyRequirementUsage)null).ComputeSatisfiedRequirement(), Throws.TypeOf());
+ Assert.That(() => ((ISatisfyRequirementUsage)null).ComputeSatisfiedRequirement(), Throws.TypeOf());
+
+ // No ownedReferenceSubsetting → AssertConstraintUsage.assertedConstraint returns subject itself,
+ // which IS-A IRequirementUsage (ISatisfyRequirementUsage : IRequirementUsage) → returns subject.
+ var selfFallbackUsage = new SatisfyRequirementUsage();
+
+ Assert.That(selfFallbackUsage.ComputeSatisfiedRequirement(), Is.SameAs(selfFallbackUsage));
+
+ // ownedReferenceSubsetting points to a RequirementUsage → returns it.
+ var withReqRefUsage = new SatisfyRequirementUsage();
+ var targetRequirement = new RequirementUsage();
+ var refSubsetting = new ReferenceSubsetting { ReferencedFeature = targetRequirement };
+ withReqRefUsage.AssignOwnership(refSubsetting);
+
+ Assert.That(withReqRefUsage.ComputeSatisfiedRequirement(), Is.SameAs(targetRequirement));
+
+ // ownedReferenceSubsetting points to a ConstraintUsage that is NOT a RequirementUsage →
+ // assertedConstraint returns the ConstraintUsage, but the "as IRequirementUsage" cast yields null.
+ var withWrongTypeUsage = new SatisfyRequirementUsage();
+ var nonRequirementTarget = new ConstraintUsage();
+ var wrongRefSubsetting = new ReferenceSubsetting { ReferencedFeature = nonRequirementTarget };
+ withWrongTypeUsage.AssignOwnership(wrongRefSubsetting);
+
+ Assert.That(withWrongTypeUsage.ComputeSatisfiedRequirement(), Is.Null);
}
+
[Test]
- public void ComputeSatisfyingFeature_ThrowsNotSupportedException()
+ public void VerifyComputeSatisfyingFeature()
{
- Assert.That(() => ((ISatisfyRequirementUsage)null).ComputeSatisfyingFeature(), Throws.TypeOf());
+ Assert.That(() => ((ISatisfyRequirementUsage)null).ComputeSatisfyingFeature(), Throws.TypeOf());
+
+ // Empty case: no ownedMember at all → no BindingConnectors → returns null.
+ var emptyUsage = new SatisfyRequirementUsage();
+
+ Assert.That(emptyUsage.ComputeSatisfyingFeature(), Is.Null);
+
+ // Populated case: a BindingConnector with two ends, one referencing subjectParameter and one
+ // referencing a "satisfying" Feature → ComputeSatisfyingFeature returns the satisfying Feature.
+ // Constructing the chain end-to-end:
+ // srfUsage.subjectParameter ← SubjectMembership.ownedSubjectParameter
+ // bindingConnector.relatedElement
+ // ← connectorEnd.ownedReferenceSubsetting.SubsettedFeature
+ // ← featureMembership.ownedMemberFeature.Where(IsEnd).OwnedRelationship.OfType().FirstOrDefault().ReferencedFeature
+ var populatedUsage = new SatisfyRequirementUsage();
+
+ var subjectMembership = new SubjectMembership();
+ var subjectParameter = new Usage();
+ populatedUsage.AssignOwnership(subjectMembership, subjectParameter);
+
+ var satisfyingFeature = new Feature();
+
+ var endForSubject = new Feature { IsEnd = true };
+ endForSubject.AssignOwnership(new ReferenceSubsetting { ReferencedFeature = subjectParameter });
+
+ var endForSatisfying = new Feature { IsEnd = true };
+ endForSatisfying.AssignOwnership(new ReferenceSubsetting { ReferencedFeature = satisfyingFeature });
+
+ var bindingConnector = new BindingConnector();
+ bindingConnector.AssignOwnership(new FeatureMembership(), endForSubject);
+ bindingConnector.AssignOwnership(new FeatureMembership(), endForSatisfying);
+
+ populatedUsage.AssignOwnership(new FeatureMembership(), bindingConnector);
+
+ Assert.That(populatedUsage.ComputeSatisfyingFeature(), Is.SameAs(satisfyingFeature));
+
+ // Degenerate case: a BindingConnector with only ONE end (referencing subjectParameter) →
+ // bindings[0].relatedElement contains only subjectParameter → FirstOrDefault with the
+ // !ReferenceEquals(r, subjectParameter) predicate finds no match → returns null.
+ var degenUsage = new SatisfyRequirementUsage();
+
+ var degenSubjectMembership = new SubjectMembership();
+ var degenSubjectParameter = new Usage();
+ degenUsage.AssignOwnership(degenSubjectMembership, degenSubjectParameter);
+
+ var degenEnd = new Feature { IsEnd = true };
+ degenEnd.AssignOwnership(new ReferenceSubsetting { ReferencedFeature = degenSubjectParameter });
+
+ var degenBindingConnector = new BindingConnector();
+ degenBindingConnector.AssignOwnership(new FeatureMembership(), degenEnd);
+
+ degenUsage.AssignOwnership(new FeatureMembership(), degenBindingConnector);
+
+ Assert.That(degenUsage.ComputeSatisfyingFeature(), Is.Null);
}
}
}
diff --git a/SysML2.NET.Tests/Extend/VerificationCaseDefinitionExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/VerificationCaseDefinitionExtensionsTestFixture.cs
index aaf5996a6..7173e668a 100644
--- a/SysML2.NET.Tests/Extend/VerificationCaseDefinitionExtensionsTestFixture.cs
+++ b/SysML2.NET.Tests/Extend/VerificationCaseDefinitionExtensionsTestFixture.cs
@@ -50,12 +50,14 @@ public void VerifyComputeVerifiedRequirement()
Assert.That(verificationCaseDefinition.ComputeVerifiedRequirement(), Is.Empty);
- // For Later: populated case depends on IRequirementVerificationMembership.ComputeVerifiedRequirement, which is still a stub.
+ // Populated: a RequirementVerificationMembership inside objectiveRequirement.featureMembership,
+ // carrying a verifiedRequirement RequirementUsage with no ownedReferenceSubsetting →
+ // ComputeVerifiedRequirement falls back to ownedRequirement (the verifiedRequirement itself).
var requirementVerificationMembership = new RequirementVerificationMembership();
var verifiedRequirement = new RequirementUsage();
requirementUsage.AssignOwnership(requirementVerificationMembership, verifiedRequirement);
- Assert.That(() => verificationCaseDefinition.ComputeVerifiedRequirement(), Throws.TypeOf());
+ Assert.That(verificationCaseDefinition.ComputeVerifiedRequirement(), Is.EqualTo([verifiedRequirement]));
}
}
}
diff --git a/SysML2.NET.Tests/Extend/VerificationCaseUsageExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/VerificationCaseUsageExtensionsTestFixture.cs
index a7ac9b288..6f14d0b2c 100644
--- a/SysML2.NET.Tests/Extend/VerificationCaseUsageExtensionsTestFixture.cs
+++ b/SysML2.NET.Tests/Extend/VerificationCaseUsageExtensionsTestFixture.cs
@@ -76,12 +76,14 @@ public void VerifyComputeVerifiedRequirement()
Assert.That(verificationCaseUsage.ComputeVerifiedRequirement(), Is.Empty);
- // For Later: populated case depends on IRequirementVerificationMembership.ComputeVerifiedRequirement, which is still a stub.
+ // Populated: a RequirementVerificationMembership inside objectiveRequirement.featureMembership,
+ // carrying a verifiedRequirement RequirementUsage with no ownedReferenceSubsetting →
+ // ComputeVerifiedRequirement falls back to ownedRequirement (the verifiedRequirement itself).
var requirementVerificationMembership = new RequirementVerificationMembership();
var verifiedRequirement = new RequirementUsage();
requirementUsage.AssignOwnership(requirementVerificationMembership, verifiedRequirement);
- Assert.That(() => verificationCaseUsage.ComputeVerifiedRequirement(), Throws.TypeOf());
+ Assert.That(verificationCaseUsage.ComputeVerifiedRequirement(), Is.EqualTo([verifiedRequirement]));
}
}
}
diff --git a/SysML2.NET.Tests/Extend/ViewpointDefinitionExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/ViewpointDefinitionExtensionsTestFixture.cs
index 1903b9710..2ea596ea3 100644
--- a/SysML2.NET.Tests/Extend/ViewpointDefinitionExtensionsTestFixture.cs
+++ b/SysML2.NET.Tests/Extend/ViewpointDefinitionExtensionsTestFixture.cs
@@ -42,13 +42,14 @@ public void VerifyComputeViewpointStakeholder()
// Empty: no framedConcern (no FramedConcernMembership in featureMembership) → empty result.
Assert.That(viewpointDefinition.ComputeViewpointStakeholder(), Is.Empty);
- // Populated case: FramedConcernMembership is present; accessing framedConcern calls
- // FramedConcernMembershipExtensions.ComputeOwnedConcern which is an out-of-scope stub.
+ // Populated: a FramedConcernMembership carrying a bare ConcernUsage (no StakeholderMembership
+ // inside its featureMembership) → the OCL chain framedConcern.featureMembership
+ // .selectByKind(StakeholderMembership).ownedStakeholderParameter projects to empty.
var framedMembership = new FramedConcernMembership();
var concernUsage = new ConcernUsage();
viewpointDefinition.AssignOwnership(framedMembership, concernUsage);
- Assert.That(() => viewpointDefinition.ComputeViewpointStakeholder(), Throws.TypeOf());
+ Assert.That(viewpointDefinition.ComputeViewpointStakeholder(), Is.Empty);
}
}
}
diff --git a/SysML2.NET.Tests/Extend/ViewpointUsageExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/ViewpointUsageExtensionsTestFixture.cs
index 0250100cd..86db1ef0d 100644
--- a/SysML2.NET.Tests/Extend/ViewpointUsageExtensionsTestFixture.cs
+++ b/SysML2.NET.Tests/Extend/ViewpointUsageExtensionsTestFixture.cs
@@ -76,13 +76,14 @@ public void VerifyComputeViewpointStakeholder()
// Empty: no framedConcern (no FramedConcernMembership in featureMembership) → empty result.
Assert.That(viewpointUsage.ComputeViewpointStakeholder(), Is.Empty);
- // Populated case: FramedConcernMembership is present; accessing framedConcern calls
- // FramedConcernMembershipExtensions.ComputeOwnedConcern which is an out-of-scope stub.
+ // Populated: a FramedConcernMembership carrying a bare ConcernUsage (no StakeholderMembership
+ // inside its featureMembership) → the OCL chain framedConcern.featureMembership
+ // .selectByKind(StakeholderMembership).ownedStakeholderParameter projects to empty.
var framedMembership = new FramedConcernMembership();
var concernUsage = new ConcernUsage();
viewpointUsage.AssignOwnership(framedMembership, concernUsage);
- Assert.That(() => viewpointUsage.ComputeViewpointStakeholder(), Throws.TypeOf());
+ Assert.That(viewpointUsage.ComputeViewpointStakeholder(), Is.Empty);
}
}
}
diff --git a/SysML2.NET/Extend/ActorMembershipExtensions.cs b/SysML2.NET/Extend/ActorMembershipExtensions.cs
index bb8c08185..272a42b28 100644
--- a/SysML2.NET/Extend/ActorMembershipExtensions.cs
+++ b/SysML2.NET/Extend/ActorMembershipExtensions.cs
@@ -32,6 +32,7 @@ namespace SysML2.NET.Core.POCO.Systems.Requirements
using SysML2.NET.Core.POCO.Root.Elements;
using SysML2.NET.Core.POCO.Root.Namespaces;
using SysML2.NET.Core.POCO.Systems.Parts;
+ using SysML2.NET.Extensions;
///
/// The class provides extensions methods for
@@ -48,10 +49,14 @@ internal static class ActorMembershipExtensions
///
/// the computed result
///
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
internal static IPartUsage ComputeOwnedActorParameter(this IActorMembership actorMembershipSubject)
{
- throw new NotSupportedException("Create a GitHub issue when this method is required");
+ if (actorMembershipSubject == null)
+ {
+ throw new ArgumentNullException(nameof(actorMembershipSubject));
+ }
+
+ return actorMembershipSubject.OwnedRelatedElement.RequireSingleOfType(nameof(actorMembershipSubject));
}
}
diff --git a/SysML2.NET/Extend/AssertConstraintUsageExtensions.cs b/SysML2.NET/Extend/AssertConstraintUsageExtensions.cs
index 773135ad8..19933aa5c 100644
--- a/SysML2.NET/Extend/AssertConstraintUsageExtensions.cs
+++ b/SysML2.NET/Extend/AssertConstraintUsageExtensions.cs
@@ -83,10 +83,21 @@ internal static class AssertConstraintUsageExtensions
///
/// the computed result
///
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
internal static IConstraintUsage ComputeAssertedConstraint(this IAssertConstraintUsage assertConstraintUsageSubject)
{
- throw new NotSupportedException("Create a GitHub issue when this method is required");
+ if (assertConstraintUsageSubject == null)
+ {
+ throw new ArgumentNullException(nameof(assertConstraintUsageSubject));
+ }
+
+ var referencedFeature = assertConstraintUsageSubject.ReferencedFeatureTarget();
+
+ if (referencedFeature == null)
+ {
+ return assertConstraintUsageSubject;
+ }
+
+ return referencedFeature as IConstraintUsage;
}
}
diff --git a/SysML2.NET/Extend/ConstraintUsageExtensions.cs b/SysML2.NET/Extend/ConstraintUsageExtensions.cs
index 3971d3e9e..25e1d6be9 100644
--- a/SysML2.NET/Extend/ConstraintUsageExtensions.cs
+++ b/SysML2.NET/Extend/ConstraintUsageExtensions.cs
@@ -22,6 +22,7 @@ namespace SysML2.NET.Core.POCO.Systems.Constraints
{
using System;
using System.Collections.Generic;
+ using System.Linq;
using SysML2.NET.Core.Core.Types;
using SysML2.NET.Core.Root.Namespaces;
@@ -72,10 +73,15 @@ internal static class ConstraintUsageExtensions
///
/// the computed result
///
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
internal static IPredicate ComputeConstraintDefinition(this IConstraintUsage constraintUsageSubject)
{
- throw new NotSupportedException("Create a GitHub issue when this method is required");
+ return constraintUsageSubject == null
+ ? throw new ArgumentNullException(nameof(constraintUsageSubject))
+ : constraintUsageSubject.OwnedRelationship
+ .OfType()
+ .Select(featureTyping => featureTyping.Type)
+ .OfType()
+ .FirstOrDefault();
}
///
@@ -101,10 +107,22 @@ internal static IPredicate ComputeConstraintDefinition(this IConstraintUsage con
///
/// The expected
///
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
internal static IFeature ComputeRedefinedNamingFeatureOperation(this IConstraintUsage constraintUsageSubject)
{
- throw new NotSupportedException("Create a GitHub issue when this method is required");
+ if (constraintUsageSubject == null)
+ {
+ throw new ArgumentNullException(nameof(constraintUsageSubject));
+ }
+
+ if (constraintUsageSubject.owningFeatureMembership is IRequirementConstraintMembership
+ && constraintUsageSubject.ownedReferenceSubsetting != null)
+ {
+ return constraintUsageSubject.ownedReferenceSubsetting.ReferencedFeature?.featureTarget;
+ }
+
+ // OCL: self.oclAsType(OccurrenceUsage).namingFeature() — explicit upcast bypass.
+ // OccurrenceUsage does not override Usage::namingFeature, so dispatch resolves to Usage's body.
+ return UsageExtensions.ComputeRedefinedNamingFeatureOperation(constraintUsageSubject);
}
///
@@ -125,10 +143,14 @@ internal static IFeature ComputeRedefinedNamingFeatureOperation(this IConstraint
///
/// The expected
///
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
internal static bool ComputeRedefinedModelLevelEvaluableOperation(this IConstraintUsage constraintUsageSubject, List visited)
{
- throw new NotSupportedException("Create a GitHub issue when this method is required");
+ if (constraintUsageSubject == null)
+ {
+ throw new ArgumentNullException(nameof(constraintUsageSubject));
+ }
+
+ return false;
}
}
}
diff --git a/SysML2.NET/Extend/FramedConcernMembershipExtensions.cs b/SysML2.NET/Extend/FramedConcernMembershipExtensions.cs
index 28dd5fa59..038bbf870 100644
--- a/SysML2.NET/Extend/FramedConcernMembershipExtensions.cs
+++ b/SysML2.NET/Extend/FramedConcernMembershipExtensions.cs
@@ -31,6 +31,7 @@ namespace SysML2.NET.Core.POCO.Systems.Requirements
using SysML2.NET.Core.POCO.Root.Elements;
using SysML2.NET.Core.POCO.Root.Namespaces;
using SysML2.NET.Core.POCO.Systems.Constraints;
+ using SysML2.NET.Extensions;
///
/// The class provides extensions methods for
@@ -47,10 +48,14 @@ internal static class FramedConcernMembershipExtensions
///
/// the computed result
///
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
internal static IConcernUsage ComputeOwnedConcern(this IFramedConcernMembership framedConcernMembershipSubject)
{
- throw new NotSupportedException("Create a GitHub issue when this method is required");
+ if (framedConcernMembershipSubject == null)
+ {
+ throw new ArgumentNullException(nameof(framedConcernMembershipSubject));
+ }
+
+ return framedConcernMembershipSubject.OwnedRelatedElement.RequireSingleOfType(nameof(framedConcernMembershipSubject));
}
///
@@ -62,10 +67,23 @@ internal static IConcernUsage ComputeOwnedConcern(this IFramedConcernMembership
///
/// the computed result
///
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
internal static IConcernUsage ComputeReferencedConcern(this IFramedConcernMembership framedConcernMembershipSubject)
{
- throw new NotSupportedException("Create a GitHub issue when this method is required");
+ if (framedConcernMembershipSubject == null)
+ {
+ throw new ArgumentNullException(nameof(framedConcernMembershipSubject));
+ }
+
+ var ownedConcern = framedConcernMembershipSubject.ownedConcern;
+
+ var referencedFeature = ownedConcern?.ReferencedFeatureTarget();
+
+ if (referencedFeature == null)
+ {
+ return ownedConcern;
+ }
+
+ return referencedFeature as IConcernUsage;
}
}
diff --git a/SysML2.NET/Extend/RequirementVerificationMembershipExtensions.cs b/SysML2.NET/Extend/RequirementVerificationMembershipExtensions.cs
index f527749e7..b52d7eefb 100644
--- a/SysML2.NET/Extend/RequirementVerificationMembershipExtensions.cs
+++ b/SysML2.NET/Extend/RequirementVerificationMembershipExtensions.cs
@@ -32,6 +32,7 @@ namespace SysML2.NET.Core.POCO.Systems.VerificationCases
using SysML2.NET.Core.POCO.Root.Namespaces;
using SysML2.NET.Core.POCO.Systems.Constraints;
using SysML2.NET.Core.POCO.Systems.Requirements;
+ using SysML2.NET.Extensions;
///
/// The class provides extensions methods for
@@ -48,10 +49,14 @@ internal static class RequirementVerificationMembershipExtensions
///
/// the computed result
///
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
internal static IRequirementUsage ComputeOwnedRequirement(this IRequirementVerificationMembership requirementVerificationMembershipSubject)
{
- throw new NotSupportedException("Create a GitHub issue when this method is required");
+ if (requirementVerificationMembershipSubject == null)
+ {
+ throw new ArgumentNullException(nameof(requirementVerificationMembershipSubject));
+ }
+
+ return requirementVerificationMembershipSubject.OwnedRelatedElement.RequireSingleOfType(nameof(requirementVerificationMembershipSubject));
}
///
@@ -63,10 +68,23 @@ internal static IRequirementUsage ComputeOwnedRequirement(this IRequirementVerif
///
/// the computed result
///
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
internal static IRequirementUsage ComputeVerifiedRequirement(this IRequirementVerificationMembership requirementVerificationMembershipSubject)
{
- throw new NotSupportedException("Create a GitHub issue when this method is required");
+ if (requirementVerificationMembershipSubject == null)
+ {
+ throw new ArgumentNullException(nameof(requirementVerificationMembershipSubject));
+ }
+
+ var ownedRequirement = requirementVerificationMembershipSubject.ownedRequirement;
+
+ var referencedFeature = ownedRequirement?.ReferencedFeatureTarget();
+
+ if (referencedFeature == null)
+ {
+ return ownedRequirement;
+ }
+
+ return referencedFeature as IRequirementUsage;
}
}
diff --git a/SysML2.NET/Extend/SatisfyRequirementUsageExtensions.cs b/SysML2.NET/Extend/SatisfyRequirementUsageExtensions.cs
index 2eedbba1e..7e0d60669 100644
--- a/SysML2.NET/Extend/SatisfyRequirementUsageExtensions.cs
+++ b/SysML2.NET/Extend/SatisfyRequirementUsageExtensions.cs
@@ -22,6 +22,7 @@ namespace SysML2.NET.Core.POCO.Systems.Requirements
{
using System;
using System.Collections.Generic;
+ using System.Linq;
using SysML2.NET.Core.Core.Types;
using SysML2.NET.Core.Root.Namespaces;
@@ -31,6 +32,7 @@ namespace SysML2.NET.Core.POCO.Systems.Requirements
using SysML2.NET.Core.POCO.Core.Types;
using SysML2.NET.Core.POCO.Kernel.Behaviors;
using SysML2.NET.Core.POCO.Kernel.Classes;
+ using SysML2.NET.Core.POCO.Kernel.Connectors;
using SysML2.NET.Core.POCO.Kernel.Functions;
using SysML2.NET.Core.POCO.Root.Annotations;
using SysML2.NET.Core.POCO.Root.Elements;
@@ -72,10 +74,24 @@ internal static class SatisfyRequirementUsageExtensions
///
/// the computed result
///
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
internal static IRequirementUsage ComputeSatisfiedRequirement(this ISatisfyRequirementUsage satisfyRequirementUsageSubject)
{
- throw new NotSupportedException("Create a GitHub issue when this method is required");
+ if (satisfyRequirementUsageSubject == null)
+ {
+ throw new ArgumentNullException(nameof(satisfyRequirementUsageSubject));
+ }
+
+ // The static-extension call (rather than the POCO-instance assertedConstraint dispatch) is
+ // correct AND safe for three independent reasons:
+ // (1) Spec equivalence: "the assertedConstraint of the SatisfyRequirementUsage considered as
+ // an AssertConstraintUsage" — the phrase "considered as" is the prose-equivalent of
+ // oclAsType(AssertConstraintUsage), triggering the CLAUDE.md static-extension exception.
+ // (2) Leaf metaclass: SatisfyRequirementUsage has no subclasses (verified in AutoGenPoco),
+ // so there is no redefinition for virtual dispatch to honour — bypass is observation-safe.
+ // (3) Recursion avoidance: subject.assertedConstraint dispatches via the explicit interface
+ // implementation IAssertConstraintUsage.assertedConstraint => satisfiedRequirement, which
+ // would re-enter this method and infinite-loop.
+ return AssertConstraintUsageExtensions.ComputeAssertedConstraint(satisfyRequirementUsageSubject) as IRequirementUsage;
}
///
@@ -101,10 +117,29 @@ internal static IRequirementUsage ComputeSatisfiedRequirement(this ISatisfyRequi
///
/// the computed result
///
- [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
internal static IFeature ComputeSatisfyingFeature(this ISatisfyRequirementUsage satisfyRequirementUsageSubject)
{
- throw new NotSupportedException("Create a GitHub issue when this method is required");
+ if (satisfyRequirementUsageSubject == null)
+ {
+ throw new ArgumentNullException(nameof(satisfyRequirementUsageSubject));
+ }
+
+ var subjectParameter = satisfyRequirementUsageSubject.subjectParameter;
+
+ var bindings = satisfyRequirementUsageSubject.ownedMember
+ .OfType()
+ .Where(bindingConnector => bindingConnector.relatedElement.Contains(subjectParameter))
+ .ToList();
+
+ if (bindings.Count == 0)
+ {
+ return null;
+ }
+
+ // OCL: bindings->first().relatedElement->any(r | r <> subjectParameter) — i.e. return the first
+ // related element other than subjectParameter (or null when none exists, matching the OCL "exits"
+ // typo — semantically "no other element exists" → null).
+ return bindings[0].relatedElement.FirstOrDefault(relatedElement => !ReferenceEquals(relatedElement, subjectParameter)) as IFeature;
}
}