From a4e52aef210f501b9c595d3a7071bfde381a6679 Mon Sep 17 00:00:00 2001 From: atheate Date: Wed, 27 May 2026 11:15:17 +0200 Subject: [PATCH] Fix #167 #179 #185 #187 --- ...eferenceSubsettingExtensionsTestFixture.cs | 37 ++++++++++--- .../SpecializationExtensionsTestFixture.cs | 39 +++++++++++--- .../SubclassificationExtensionsTestFixture.cs | 34 +++++++++--- .../Extend/SubsettingExtensionsTestFixture.cs | 31 ++++++++--- SysML2.NET.sln.DotSettings | 2 +- .../Extend/ReferenceSubsettingExtensions.cs | 52 +++++++++++-------- SysML2.NET/Extend/SpecializationExtensions.cs | 35 ++++++------- .../Extend/SubclassificationExtensions.cs | 36 ++++++------- SysML2.NET/Extend/SubsettingExtensions.cs | 36 ++++++------- 9 files changed, 193 insertions(+), 109 deletions(-) diff --git a/SysML2.NET.Tests/Extend/ReferenceSubsettingExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/ReferenceSubsettingExtensionsTestFixture.cs index feef80d39..51de1ef83 100644 --- a/SysML2.NET.Tests/Extend/ReferenceSubsettingExtensionsTestFixture.cs +++ b/SysML2.NET.Tests/Extend/ReferenceSubsettingExtensionsTestFixture.cs @@ -1,7 +1,7 @@ -// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // -// Copyright 2022-2026 Starion Group S.A. +// Copyright (C) 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. @@ -21,18 +21,43 @@ 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.Exceptions; [TestFixture] public class ReferenceSubsettingExtensionsTestFixture { [Test] - public void ComputeReferencingFeature_ThrowsNotSupportedException() + public void VerifyComputeReferencingFeature() { - Assert.That(() => ((IReferenceSubsetting)null).ComputeReferencingFeature(), Throws.TypeOf()); + // Null subject → ArgumentNullException. + Assert.That(() => ((IReferenceSubsetting)null).ComputeReferencingFeature(), Throws.TypeOf()); + + // Empty ReferenceSubsetting (OwningRelatedElement is null) → [1..1] violation: IncompleteModelException. + var emptySubsetting = new ReferenceSubsetting(); + + Assert.That(() => emptySubsetting.ComputeReferencingFeature(), Throws.TypeOf()); + + // OwningRelatedElement is an IFeature → returns the same instance. + var feature = new Feature(); + var refSubsettingWithFeature = new ReferenceSubsetting(); + + ((IContainedRelationship)refSubsettingWithFeature).OwningRelatedElement = feature; + + Assert.That(refSubsettingWithFeature.ComputeReferencingFeature(), Is.SameAs(feature)); + + // OwningRelatedElement is a non-IFeature (Namespace) → [1..1] type violation: IncompleteModelException. + var namespaceObj = new Namespace(); + var refSubsettingWithNamespace = new ReferenceSubsetting(); + + ((IContainedRelationship)refSubsettingWithNamespace).OwningRelatedElement = namespaceObj; + + Assert.That(() => refSubsettingWithNamespace.ComputeReferencingFeature(), Throws.TypeOf()); } } } diff --git a/SysML2.NET.Tests/Extend/SpecializationExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/SpecializationExtensionsTestFixture.cs index 69c7280c1..c3c842207 100644 --- a/SysML2.NET.Tests/Extend/SpecializationExtensionsTestFixture.cs +++ b/SysML2.NET.Tests/Extend/SpecializationExtensionsTestFixture.cs @@ -1,7 +1,7 @@ -// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // -// Copyright 2022-2026 Starion Group S.A. +// Copyright (C) 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. @@ -21,18 +21,45 @@ namespace SysML2.NET.Tests.Extend { using System; - + using NUnit.Framework; - + using SysML2.NET.Core.POCO.Core.Types; + using SysML2.NET.Core.POCO.Root.Elements; + using SysML2.NET.Core.POCO.Root.Namespaces; + using SysML2.NET.Extensions; + + using Type = SysML2.NET.Core.POCO.Core.Types.Type; [TestFixture] public class SpecializationExtensionsTestFixture { [Test] - public void ComputeOwningType_ThrowsNotSupportedException() + public void VerifyComputeOwningType() { - Assert.That(() => ((ISpecialization)null).ComputeOwningType(), Throws.TypeOf()); + Assert.That(() => ((ISpecialization)null).ComputeOwningType(), Throws.TypeOf()); + + var emptySpecialization = new Specialization(); + + Assert.That(emptySpecialization.ComputeOwningType(), Is.Null); + + var owningType = new Type(); + var specialization = new Specialization(); + + owningType.AssignOwnership(specialization); + + Assert.That(specialization.ComputeOwningType(), Is.SameAs(owningType)); + + // NOTE: assigning a non-IType as OwningRelatedElement is not guarded by the public + // AssignOwnership API for Specialization, so we directly set the backing field via + // the IContainedRelationship explicit interface to exercise the as-cast-returns-null + // path, which proves ComputeOwningType returns null when the owner is not an IType. + var nonTypeSpecialization = new Specialization(); + var nonTypeOwner = new Namespace(); + + ((IContainedRelationship)nonTypeSpecialization).OwningRelatedElement = nonTypeOwner; + + Assert.That(nonTypeSpecialization.ComputeOwningType(), Is.Null); } } } diff --git a/SysML2.NET.Tests/Extend/SubclassificationExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/SubclassificationExtensionsTestFixture.cs index 09a428db3..35f93a1ae 100644 --- a/SysML2.NET.Tests/Extend/SubclassificationExtensionsTestFixture.cs +++ b/SysML2.NET.Tests/Extend/SubclassificationExtensionsTestFixture.cs @@ -1,7 +1,7 @@ -// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // -// Copyright 2022-2026 Starion Group S.A. +// Copyright (C) 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. @@ -21,18 +21,40 @@ namespace SysML2.NET.Tests.Extend { using System; - + using NUnit.Framework; - + using SysML2.NET.Core.POCO.Core.Classifiers; + using SysML2.NET.Core.POCO.Root.Elements; + using SysML2.NET.Core.POCO.Root.Namespaces; [TestFixture] public class SubclassificationExtensionsTestFixture { [Test] - public void ComputeOwningClassifier_ThrowsNotSupportedException() + public void VerifyComputeOwningClassifier() { - Assert.That(() => ((ISubclassification)null).ComputeOwningClassifier(), Throws.TypeOf()); + Assert.That(() => ((ISubclassification)null).ComputeOwningClassifier(), Throws.TypeOf()); + + // Empty Subclassification (OwningRelatedElement is null) → returns null. + var subclassification = new Subclassification(); + + Assert.That(subclassification.ComputeOwningClassifier(), Is.Null); + + // OwningRelatedElement is an IClassifier → returns the classifier. + var classifier = new Classifier(); + + ((IContainedRelationship)subclassification).OwningRelatedElement = classifier; + + Assert.That(subclassification.ComputeOwningClassifier(), Is.SameAs(classifier)); + + // OwningRelatedElement is NOT an IClassifier (e.g. Namespace) → returns null. + var nonClassifierSubclassification = new Subclassification(); + var namespaceObj = new Namespace(); + + ((IContainedRelationship)nonClassifierSubclassification).OwningRelatedElement = namespaceObj; + + Assert.That(nonClassifierSubclassification.ComputeOwningClassifier(), Is.Null); } } } diff --git a/SysML2.NET.Tests/Extend/SubsettingExtensionsTestFixture.cs b/SysML2.NET.Tests/Extend/SubsettingExtensionsTestFixture.cs index 140fd5a06..a7515d400 100644 --- a/SysML2.NET.Tests/Extend/SubsettingExtensionsTestFixture.cs +++ b/SysML2.NET.Tests/Extend/SubsettingExtensionsTestFixture.cs @@ -1,7 +1,7 @@ -// ------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------- // // -// Copyright 2022-2026 Starion Group S.A. +// Copyright (C) 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. @@ -21,18 +21,37 @@ 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 SubsettingExtensionsTestFixture { [Test] - public void ComputeOwningFeature_ThrowsNotSupportedException() + public void VerifyComputeOwningFeature() { - Assert.That(() => ((ISubsetting)null).ComputeOwningFeature(), Throws.TypeOf()); + Assert.That(() => ((ISubsetting)null).ComputeOwningFeature(), Throws.TypeOf()); + + var subsetting = new Subsetting(); + + Assert.That(subsetting.ComputeOwningFeature(), Is.Null); + + var feature = new Feature(); + + ((IContainedRelationship)subsetting).OwningRelatedElement = feature; + + Assert.That(subsetting.ComputeOwningFeature(), Is.SameAs(feature)); + + var namespaceOwner = new Namespace(); + var nonFeatureSubsetting = new Subsetting(); + + ((IContainedRelationship)nonFeatureSubsetting).OwningRelatedElement = namespaceOwner; + + Assert.That(nonFeatureSubsetting.ComputeOwningFeature(), Is.Null); } } } diff --git a/SysML2.NET.sln.DotSettings b/SysML2.NET.sln.DotSettings index fee640aa2..67c558f95 100644 --- a/SysML2.NET.sln.DotSettings +++ b/SysML2.NET.sln.DotSettings @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------------------------- <copyright file="${File.FileName}" company="Starion Group S.A."> - Copyright 2022-2026 Starion Group S.A. + Copyright (C) 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. diff --git a/SysML2.NET/Extend/ReferenceSubsettingExtensions.cs b/SysML2.NET/Extend/ReferenceSubsettingExtensions.cs index 2d0ca2f2e..444cd2b6f 100644 --- a/SysML2.NET/Extend/ReferenceSubsettingExtensions.cs +++ b/SysML2.NET/Extend/ReferenceSubsettingExtensions.cs @@ -1,53 +1,61 @@ // ------------------------------------------------------------------------------------------------- // -// -// Copyright (C) 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 -// +// +// Copyright (C) 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.Core.POCO.Core.Features { using System; - using System.Collections.Generic; - using SysML2.NET.Core.POCO.Core.Types; - 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 - /// the interface + /// The class provides extensions methods for + /// the interface /// internal static class ReferenceSubsettingExtensions { /// - /// Computes the derived property. + /// Computes the derived property referencingFeature — the that owns + /// this relationship, which is also its subsettingFeature. /// /// - /// The subject + /// The subject /// /// - /// the computed result + /// The that is the owning related element of this relationship. /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + /// + /// Thrown when is null. + /// + /// + /// Thrown when the owning related element is null or is not an . + /// internal static IFeature ComputeReferencingFeature(this IReferenceSubsetting referenceSubsettingSubject) { - throw new NotSupportedException("Create a GitHub issue when this method is required"); - } + if (referenceSubsettingSubject == null) + { + throw new ArgumentNullException(nameof(referenceSubsettingSubject)); + } + return referenceSubsettingSubject.OwningRelatedElement as IFeature + ?? throw new IncompleteModelException( + $"{nameof(referenceSubsettingSubject)} must have an owning related element of type {nameof(IFeature)}"); + } } } diff --git a/SysML2.NET/Extend/SpecializationExtensions.cs b/SysML2.NET/Extend/SpecializationExtensions.cs index 62bf4780c..c6284003c 100644 --- a/SysML2.NET/Extend/SpecializationExtensions.cs +++ b/SysML2.NET/Extend/SpecializationExtensions.cs @@ -1,35 +1,30 @@ // ------------------------------------------------------------------------------------------------- // -// -// Copyright (C) 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 -// +// +// Copyright (C) 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.Core.POCO.Core.Types { using System; - using System.Collections.Generic; - - using SysML2.NET.Core.POCO.Root.Annotations; - using SysML2.NET.Core.POCO.Root.Elements; - using SysML2.NET.Core.POCO.Root.Namespaces; /// - /// The class provides extensions methods for - /// the interface + /// The class provides extensions methods for + /// the interface /// internal static class SpecializationExtensions { @@ -37,16 +32,16 @@ internal static class SpecializationExtensions /// Computes the derived property. /// /// - /// The subject + /// The subject /// /// /// the computed result /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] internal static IType ComputeOwningType(this ISpecialization specializationSubject) { - throw new NotSupportedException("Create a GitHub issue when this method is required"); + return specializationSubject == null + ? throw new ArgumentNullException(nameof(specializationSubject)) + : specializationSubject.OwningRelatedElement as IType; } - } } diff --git a/SysML2.NET/Extend/SubclassificationExtensions.cs b/SysML2.NET/Extend/SubclassificationExtensions.cs index 858b90edd..2a6b9d6d6 100644 --- a/SysML2.NET/Extend/SubclassificationExtensions.cs +++ b/SysML2.NET/Extend/SubclassificationExtensions.cs @@ -1,36 +1,30 @@ // ------------------------------------------------------------------------------------------------- // -// -// Copyright (C) 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 -// +// +// Copyright (C) 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.Core.POCO.Core.Classifiers { using System; - using System.Collections.Generic; - - using SysML2.NET.Core.POCO.Core.Types; - using SysML2.NET.Core.POCO.Root.Annotations; - using SysML2.NET.Core.POCO.Root.Elements; - using SysML2.NET.Core.POCO.Root.Namespaces; /// - /// The class provides extensions methods for - /// the interface + /// The class provides extensions methods for + /// the interface /// internal static class SubclassificationExtensions { @@ -38,16 +32,16 @@ internal static class SubclassificationExtensions /// Computes the derived property. /// /// - /// The subject + /// The subject /// /// /// the computed result /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] internal static IClassifier ComputeOwningClassifier(this ISubclassification subclassificationSubject) { - throw new NotSupportedException("Create a GitHub issue when this method is required"); + return subclassificationSubject == null + ? throw new ArgumentNullException(nameof(subclassificationSubject)) + : subclassificationSubject.OwningRelatedElement as IClassifier; } - } } diff --git a/SysML2.NET/Extend/SubsettingExtensions.cs b/SysML2.NET/Extend/SubsettingExtensions.cs index bb3a618df..4e095e81c 100644 --- a/SysML2.NET/Extend/SubsettingExtensions.cs +++ b/SysML2.NET/Extend/SubsettingExtensions.cs @@ -1,36 +1,30 @@ // ------------------------------------------------------------------------------------------------- // -// -// Copyright (C) 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 -// +// +// Copyright (C) 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.Core.POCO.Core.Features { using System; - using System.Collections.Generic; - - using SysML2.NET.Core.POCO.Core.Types; - using SysML2.NET.Core.POCO.Root.Annotations; - using SysML2.NET.Core.POCO.Root.Elements; - using SysML2.NET.Core.POCO.Root.Namespaces; /// - /// The class provides extensions methods for - /// the interface + /// The class provides extensions methods for + /// the interface /// internal static class SubsettingExtensions { @@ -38,16 +32,16 @@ internal static class SubsettingExtensions /// Computes the derived property. /// /// - /// The subject + /// The subject /// /// /// the computed result /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] internal static IFeature ComputeOwningFeature(this ISubsetting subsettingSubject) { - throw new NotSupportedException("Create a GitHub issue when this method is required"); + return subsettingSubject == null + ? throw new ArgumentNullException(nameof(subsettingSubject)) + : subsettingSubject.OwningRelatedElement as IFeature; } - } }