From 403e8cd61b3dd36cdc3d068cf3c83ff76bcdfd8f Mon Sep 17 00:00:00 2001 From: atheate Date: Wed, 13 May 2026 14:21:49 +0200 Subject: [PATCH] Fix #161 --- ...arameterMembershipExtensionsTestFixture.cs | 75 ++++++++++++++++--- .../Extend/ParameterMembershipExtensions.cs | 19 ++++- 2 files changed, 80 insertions(+), 14 deletions(-) diff --git a/SysML2.NET.Tests/Extend/ParameterMembershipExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/ParameterMembershipExtensionsTestFixture.cs index c35b71c7..519f40bb 100644 --- a/SysML2.NET.Tests/Extend/ParameterMembershipExtensionsTestFixture.cs +++ b/SysML2.NET.Tests/Extend/ParameterMembershipExtensionsTestFixture.cs @@ -1,38 +1,93 @@ -// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // -// +// // 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.Core.Types; + using SysML2.NET.Core.POCO.Core.Features; + using SysML2.NET.Core.POCO.Core.Types; using SysML2.NET.Core.POCO.Kernel.Behaviors; + using SysML2.NET.Core.POCO.Root.Elements; + using SysML2.NET.Core.POCO.Root.Namespaces; + using SysML2.NET.Exceptions; + using SysML2.NET.Extensions; + + using Type = SysML2.NET.Core.POCO.Core.Types.Type; [TestFixture] public class ParameterMembershipExtensionsTestFixture { [Test] - public void ComputeOwnedMemberParameter_ThrowsNotSupportedException() + public void VerifyComputeOwnedMemberParameter() { - Assert.That(() => ((IParameterMembership)null).ComputeOwnedMemberParameter(), Throws.TypeOf()); + Assert.That(() => ((IParameterMembership)null).ComputeOwnedMemberParameter(), Throws.TypeOf()); + + var parameterMembership = new ParameterMembership(); + + Assert.That(() => parameterMembership.ComputeOwnedMemberParameter(), Throws.TypeOf()); + + var owningType = new Type(); + var feature = new Feature(); + + owningType.AssignOwnership(parameterMembership, feature); + + Assert.That(parameterMembership.ComputeOwnedMemberParameter(), Is.SameAs(feature)); + + // Wiring two features to verify the multiple-element guard: + // First remove the existing wiring so we can create a fresh membership with two elements. + var twoElementMembership = new ParameterMembership(); + var secondFeature = new Feature(); + + ((IContainedRelationship)twoElementMembership).OwnedRelatedElement.Add(feature); + ((IContainedRelationship)twoElementMembership).OwnedRelatedElement.Add(secondFeature); + + Assert.That(() => twoElementMembership.ComputeOwnedMemberParameter(), Throws.TypeOf()); + + // NOTE: wiring a non-IFeature element as the sole OwnedRelatedElement is not possible via the + // public AssignOwnership API (IParameterMembership requires an IFeature target). + // To cover the as-cast-returns-null path we directly populate OwnedRelatedElement with a + // plain Namespace (which is not an IFeature). + var nonFeatureMembership = new ParameterMembership(); + var nonFeatureElement = new Namespace(); + + ((IContainedRelationship)nonFeatureMembership).OwnedRelatedElement.Add(nonFeatureElement); + + Assert.That(nonFeatureMembership.ComputeOwnedMemberParameter(), Is.Null); + } + + [Test] + public void VerifyComputeParameterDirectionOperation() + { + Assert.That(() => ((IParameterMembership)null).ComputeParameterDirectionOperation(), Throws.TypeOf()); + + var parameterMembership = new ParameterMembership(); + var owningType = new Type(); + var feature = new Feature(); + + owningType.AssignOwnership(parameterMembership, feature); + + Assert.That(parameterMembership.ComputeParameterDirectionOperation(), Is.EqualTo(FeatureDirectionKind.In)); } } } diff --git a/SysML2.NET/Extend/ParameterMembershipExtensions.cs b/SysML2.NET/Extend/ParameterMembershipExtensions.cs index f8c14f20..273b0f22 100644 --- a/SysML2.NET/Extend/ParameterMembershipExtensions.cs +++ b/SysML2.NET/Extend/ParameterMembershipExtensions.cs @@ -30,6 +30,7 @@ namespace SysML2.NET.Core.POCO.Kernel.Behaviors using SysML2.NET.Core.POCO.Root.Annotations; using SysML2.NET.Core.POCO.Root.Elements; using SysML2.NET.Core.POCO.Root.Namespaces; + using SysML2.NET.Exceptions; /// /// The class provides extensions methods for @@ -46,10 +47,16 @@ internal static class ParameterMembershipExtensions /// /// the computed result /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] internal static IFeature ComputeOwnedMemberParameter(this IParameterMembership parameterMembershipSubject) { - throw new NotSupportedException("Create a GitHub issue when this method is required"); + if (parameterMembershipSubject == null) + { + throw new ArgumentNullException(nameof(parameterMembershipSubject)); + } + + return parameterMembershipSubject.OwnedRelatedElement.Count != 1 + ? throw new IncompleteModelException($"{nameof(parameterMembershipSubject)} must have exactly one related element") + : parameterMembershipSubject.OwnedRelatedElement[0] as IFeature; } /// @@ -67,10 +74,14 @@ internal static IFeature ComputeOwnedMemberParameter(this IParameterMembership p /// /// The expected /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] internal static FeatureDirectionKind ComputeParameterDirectionOperation(this IParameterMembership parameterMembershipSubject) { - throw new NotSupportedException("Create a GitHub issue when this method is required"); + if (parameterMembershipSubject == null) + { + throw new ArgumentNullException(nameof(parameterMembershipSubject)); + } + + return FeatureDirectionKind.In; } } }