From c161dc2ae9c02bd4b5702bc3d4ea7ac2a49ecae2 Mon Sep 17 00:00:00 2001 From: atheate Date: Fri, 31 Jul 2026 15:37:20 +0200 Subject: [PATCH] Fix #110 #135 --- ...njugatedPortTypingExtensionsTestFixture.cs | 38 ++++++--- .../ControlNodeExtensionsTestFixture.cs | 82 +++++++++++++++++++ .../FeatureTypingExtensionsTestFixture.cs | 39 ++++++--- ...arameterMembershipExtensionsTestFixture.cs | 43 ++++++++++ .../Extend/ConjugatedPortTypingExtensions.cs | 5 +- SysML2.NET/Extend/ControlNodeExtensions.cs | 13 ++- SysML2.NET/Extend/FeatureTypingExtensions.cs | 5 +- .../ReturnParameterMembershipExtensions.cs | 5 +- 8 files changed, 202 insertions(+), 28 deletions(-) create mode 100644 SysML2.NET.Tests/Extend/ControlNodeExtensionsTestFixture.cs create mode 100644 SysML2.NET.Tests/Extend/ReturnParameterMembershipExtensionsTestFixture.cs diff --git a/SysML2.NET.Tests/Extend/ConjugatedPortTypingExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/ConjugatedPortTypingExtensionsTestFixture.cs index 34b4840b..1fa1434c 100644 --- a/SysML2.NET.Tests/Extend/ConjugatedPortTypingExtensionsTestFixture.cs +++ b/SysML2.NET.Tests/Extend/ConjugatedPortTypingExtensionsTestFixture.cs @@ -1,38 +1,56 @@ -// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // -// +// // 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.Namespaces; using SysML2.NET.Core.POCO.Systems.Ports; + using SysML2.NET.Extensions; [TestFixture] public class ConjugatedPortTypingExtensionsTestFixture { [Test] - public void ComputePortDefinition_ThrowsNotSupportedException() + public void VerifyComputePortDefinition() { - Assert.That(() => ((IConjugatedPortTyping)null).ComputePortDefinition(), Throws.TypeOf()); + Assert.That(() => ((IConjugatedPortTyping)null).ComputePortDefinition(), Throws.TypeOf()); + + // No ConjugatedPortDefinition -> the null-safe navigation short-circuits to null. + var emptyConjugatedPortTyping = new ConjugatedPortTyping(); + + Assert.That(emptyConjugatedPortTyping.ComputePortDefinition(), Is.Null); + + // Positive case: the ConjugatedPortDefinition's originalPortDefinition derives from its + // owningMembership -> membershipOwningNamespace, which must be a PortDefinition. Wire that + // ownership chain so originalPortDefinition (and thus portDefinition) resolves to the original. + var originalPortDefinition = new PortDefinition(); + var conjugatedPortDefinition = new ConjugatedPortDefinition(); + originalPortDefinition.AssignOwnership(new OwningMembership(), conjugatedPortDefinition); + + var conjugatedPortTyping = new ConjugatedPortTyping { ConjugatedPortDefinition = conjugatedPortDefinition }; + + Assert.That(conjugatedPortTyping.ComputePortDefinition(), Is.SameAs(originalPortDefinition)); } } } diff --git a/SysML2.NET.Tests/Extend/ControlNodeExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/ControlNodeExtensionsTestFixture.cs new file mode 100644 index 00000000..b4cf7acc --- /dev/null +++ b/SysML2.NET.Tests/Extend/ControlNodeExtensionsTestFixture.cs @@ -0,0 +1,82 @@ +// ------------------------------------------------------------------------------------------------- +// +// +// 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 Moq; + + using NUnit.Framework; + + using SysML2.NET.Core.POCO.Core.Types; + using SysML2.NET.Core.POCO.Kernel.Multiplicities; + using SysML2.NET.Core.POCO.Systems.Actions; + + [TestFixture] + public class ControlNodeExtensionsTestFixture + { + [Test] + public void VerifyComputeMultiplicityHasBoundsOperation() + { + // ControlNode is abstract; ForkNode is a concrete IControlNode used as the subject. + var controlNode = new ForkNode(); + + Assert.That(() => ((IControlNode)null).ComputeMultiplicityHasBoundsOperation(null, 1, "1"), Throws.TypeOf()); + + // mult == null -> false (the OCL "mult <> null" guard, not a throw). + Assert.That(controlNode.ComputeMultiplicityHasBoundsOperation(null, 1, "1"), Is.False); + + // mult IS a MultiplicityRange -> the direct branch delegates to HasBounds(lower, upper). + var range = new Mock(); + range.Setup(x => x.HasBounds(1, "5")).Returns(true); + + using (Assert.EnterMultipleScope()) + { + Assert.That(controlNode.ComputeMultiplicityHasBoundsOperation(range.Object, 1, "5"), Is.True); + + // Bounds that were not set up return Moq's default (false). + Assert.That(controlNode.ComputeMultiplicityHasBoundsOperation(range.Object, 0, "5"), Is.False); + } + + // mult is a plain Multiplicity (NOT a MultiplicityRange) -> the supertype branch searches + // AllSupertypes() for a MultiplicityRange whose HasBounds(lower, upper) is true. + var rangeSupertype = new Mock(); + rangeSupertype.Setup(x => x.HasBounds(1, "5")).Returns(true); + + var multiplicityWithRangeSupertype = new Mock(); + multiplicityWithRangeSupertype.Setup(x => x.AllSupertypes()).Returns([rangeSupertype.Object]); + + var multiplicityWithoutRangeSupertype = new Mock(); + multiplicityWithoutRangeSupertype.Setup(x => x.AllSupertypes()).Returns([]); + + using (Assert.EnterMultipleScope()) + { + Assert.That(controlNode.ComputeMultiplicityHasBoundsOperation(multiplicityWithRangeSupertype.Object, 1, "5"), Is.True); + + // A matching MultiplicityRange supertype exists, but the requested bounds do not match. + Assert.That(controlNode.ComputeMultiplicityHasBoundsOperation(multiplicityWithRangeSupertype.Object, 0, "5"), Is.False); + + // No MultiplicityRange among the supertypes -> false. + Assert.That(controlNode.ComputeMultiplicityHasBoundsOperation(multiplicityWithoutRangeSupertype.Object, 1, "5"), Is.False); + } + } + } +} diff --git a/SysML2.NET.Tests/Extend/FeatureTypingExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/FeatureTypingExtensionsTestFixture.cs index 553e9ddb..b9f65d4c 100644 --- a/SysML2.NET.Tests/Extend/FeatureTypingExtensionsTestFixture.cs +++ b/SysML2.NET.Tests/Extend/FeatureTypingExtensionsTestFixture.cs @@ -1,38 +1,57 @@ -// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // -// +// // 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; [TestFixture] public class FeatureTypingExtensionsTestFixture { [Test] - public void ComputeOwningFeature_ThrowsNotSupportedException() + public void VerifyComputeOwningFeature() { - Assert.That(() => ((IFeatureTyping)null).ComputeOwningFeature(), Throws.TypeOf()); + Assert.That(() => ((IFeatureTyping)null).ComputeOwningFeature(), Throws.TypeOf()); + + var featureTyping = new FeatureTyping(); + + Assert.That(featureTyping.ComputeOwningFeature(), Is.Null); + + var feature = new Feature(); + + ((IContainedRelationship)featureTyping).OwningRelatedElement = feature; + + Assert.That(featureTyping.ComputeOwningFeature(), Is.SameAs(feature)); + + var namespaceOwner = new Namespace(); + var nonFeatureFeatureTyping = new FeatureTyping(); + + ((IContainedRelationship)nonFeatureFeatureTyping).OwningRelatedElement = namespaceOwner; + + Assert.That(nonFeatureFeatureTyping.ComputeOwningFeature(), Is.Null); } } } diff --git a/SysML2.NET.Tests/Extend/ReturnParameterMembershipExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/ReturnParameterMembershipExtensionsTestFixture.cs new file mode 100644 index 00000000..142328ab --- /dev/null +++ b/SysML2.NET.Tests/Extend/ReturnParameterMembershipExtensionsTestFixture.cs @@ -0,0 +1,43 @@ +// ------------------------------------------------------------------------------------------------- +// +// +// 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.Kernel.Functions; + + [TestFixture] + public class ReturnParameterMembershipExtensionsTestFixture + { + [Test] + public void VerifyComputeRedefinedParameterDirectionOperation() + { + Assert.That(() => ((IReturnParameterMembership)null).ComputeRedefinedParameterDirectionOperation(), Throws.TypeOf()); + + var returnParameterMembership = new ReturnParameterMembership(); + + Assert.That(returnParameterMembership.ComputeRedefinedParameterDirectionOperation(), Is.EqualTo(FeatureDirectionKind.Out)); + } + } +} diff --git a/SysML2.NET/Extend/ConjugatedPortTypingExtensions.cs b/SysML2.NET/Extend/ConjugatedPortTypingExtensions.cs index 807119a3..af5aff1b 100644 --- a/SysML2.NET/Extend/ConjugatedPortTypingExtensions.cs +++ b/SysML2.NET/Extend/ConjugatedPortTypingExtensions.cs @@ -50,10 +50,11 @@ internal static class ConjugatedPortTypingExtensions /// /// the computed result /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] internal static IPortDefinition ComputePortDefinition(this IConjugatedPortTyping conjugatedPortTypingSubject) { - throw new NotSupportedException("Create a GitHub issue when this method is required"); + return conjugatedPortTypingSubject == null + ? throw new ArgumentNullException(nameof(conjugatedPortTypingSubject)) + : conjugatedPortTypingSubject.ConjugatedPortDefinition?.originalPortDefinition; } } diff --git a/SysML2.NET/Extend/ControlNodeExtensions.cs b/SysML2.NET/Extend/ControlNodeExtensions.cs index 910f14f3..82604e14 100644 --- a/SysML2.NET/Extend/ControlNodeExtensions.cs +++ b/SysML2.NET/Extend/ControlNodeExtensions.cs @@ -22,10 +22,12 @@ namespace SysML2.NET.Core.POCO.Systems.Actions { using System; using System.Collections.Generic; + using System.Linq; using SysML2.NET.Core.Core.Types; using SysML2.NET.Core.Root.Namespaces; using SysML2.NET.Core.Systems.Occurrences; + using SysML2.NET.Core.POCO.Kernel.Multiplicities; using SysML2.NET.Core.POCO.Core.Classifiers; using SysML2.NET.Core.POCO.Core.Features; using SysML2.NET.Core.POCO.Core.Types; @@ -95,10 +97,17 @@ internal static class ControlNodeExtensions /// /// The expected /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] internal static bool ComputeMultiplicityHasBoundsOperation(this IControlNode controlNodeSubject, IMultiplicity mult, int lower, string upper) { - throw new NotSupportedException("Create a GitHub issue when this method is required"); + if (controlNodeSubject == null) + { + throw new ArgumentNullException(nameof(controlNodeSubject)); + } + + return mult != null + && (mult is IMultiplicityRange multiplicityRange + ? multiplicityRange.HasBounds(lower, upper) + : mult.AllSupertypes().OfType().Any(rangeSupertype => rangeSupertype.HasBounds(lower, upper))); } } } diff --git a/SysML2.NET/Extend/FeatureTypingExtensions.cs b/SysML2.NET/Extend/FeatureTypingExtensions.cs index 0b0762c1..47af06c1 100644 --- a/SysML2.NET/Extend/FeatureTypingExtensions.cs +++ b/SysML2.NET/Extend/FeatureTypingExtensions.cs @@ -43,10 +43,11 @@ internal static class FeatureTypingExtensions /// /// the computed result /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] internal static IFeature ComputeOwningFeature(this IFeatureTyping featureTypingSubject) { - throw new NotSupportedException("Create a GitHub issue when this method is required"); + return featureTypingSubject == null + ? throw new ArgumentNullException(nameof(featureTypingSubject)) + : featureTypingSubject.OwningRelatedElement as IFeature; } } diff --git a/SysML2.NET/Extend/ReturnParameterMembershipExtensions.cs b/SysML2.NET/Extend/ReturnParameterMembershipExtensions.cs index 44d92a18..3f283a64 100644 --- a/SysML2.NET/Extend/ReturnParameterMembershipExtensions.cs +++ b/SysML2.NET/Extend/ReturnParameterMembershipExtensions.cs @@ -54,10 +54,11 @@ internal static class ReturnParameterMembershipExtensions /// /// The expected /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] internal static FeatureDirectionKind ComputeRedefinedParameterDirectionOperation(this IReturnParameterMembership returnParameterMembershipSubject) { - throw new NotSupportedException("Create a GitHub issue when this method is required"); + return returnParameterMembershipSubject == null + ? throw new ArgumentNullException(nameof(returnParameterMembershipSubject)) + : FeatureDirectionKind.Out; } } }