Skip to content

Commit a955fb7

Browse files
Fix #123 (#265)
* Fix #123 * File cleanup
1 parent b0d8a2f commit a955fb7

2 files changed

Lines changed: 67 additions & 19 deletions

File tree

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,88 @@
1-
// -------------------------------------------------------------------------------------------------
1+
// -------------------------------------------------------------------------------------------------
22
// <copyright file="EndFeatureMembershipExtensionsTestFixture.cs" company="Starion Group S.A.">
3-
//
3+
//
44
// Copyright 2022-2026 Starion Group S.A.
5-
//
5+
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
88
// You may obtain a copy of the License at
9-
//
9+
//
1010
// http://www.apache.org/licenses/LICENSE-2.0
11-
//
11+
//
1212
// Unless required by applicable law or agreed to in writing, software
1313
// distributed under the License is distributed on an "AS IS" BASIS,
1414
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1515
// See the License for the specific language governing permissions and
1616
// limitations under the License.
17-
//
17+
//
1818
// </copyright>
1919
// ------------------------------------------------------------------------------------------------
2020

2121
namespace SysML2.NET.Tests.Extend
2222
{
2323
using System;
24-
24+
2525
using NUnit.Framework;
26-
26+
2727
using SysML2.NET.Core.POCO.Core.Features;
28+
using SysML2.NET.Core.POCO.Root.Elements;
29+
using SysML2.NET.Core.POCO.Root.Namespaces;
30+
using SysML2.NET.Exceptions;
31+
using SysML2.NET.Extensions;
32+
33+
using Type = SysML2.NET.Core.POCO.Core.Types.Type;
2834

2935
[TestFixture]
3036
public class EndFeatureMembershipExtensionsTestFixture
3137
{
3238
[Test]
33-
public void ComputeOwnedMemberFeature_ThrowsNotSupportedException()
39+
public void VerifyComputeOwnedMemberFeature()
3440
{
35-
Assert.That(() => ((IEndFeatureMembership)null).ComputeOwnedMemberFeature(), Throws.TypeOf<NotSupportedException>());
41+
Assert.That(() => ((IEndFeatureMembership)null).ComputeOwnedMemberFeature(), Throws.TypeOf<ArgumentNullException>());
42+
43+
// Empty OwnedRelatedElement → [1..1] violation: throws IncompleteModelException.
44+
var endFeatureMembership = new EndFeatureMembership();
45+
46+
Assert.That(() => endFeatureMembership.ComputeOwnedMemberFeature(), Throws.TypeOf<IncompleteModelException>());
47+
48+
// Single IFeature wired via the public API → returned.
49+
var owningType = new Type();
50+
var feature = new Feature();
51+
52+
owningType.AssignOwnership(endFeatureMembership, feature);
53+
54+
Assert.That(endFeatureMembership.ComputeOwnedMemberFeature(), Is.SameAs(feature));
55+
56+
// Two IFeatures in OwnedRelatedElement → [1..1] violation: throws IncompleteModelException.
57+
var twoFeatureMembership = new EndFeatureMembership();
58+
var firstFeature = new Feature();
59+
var secondFeature = new Feature();
60+
61+
((IContainedRelationship)twoFeatureMembership).OwnedRelatedElement.Add(firstFeature);
62+
((IContainedRelationship)twoFeatureMembership).OwnedRelatedElement.Add(secondFeature);
63+
64+
Assert.That(() => twoFeatureMembership.ComputeOwnedMemberFeature(), Throws.TypeOf<IncompleteModelException>());
65+
66+
// Mixed-type owned related elements: exactly one IFeature alongside a non-IFeature (Namespace).
67+
// The RequireSingleOfType<IFeature> projection MUST pick out the IFeature regardless of its position
68+
// (this is the core robustness guarantee — never positionally index the unfiltered collection).
69+
var mixedMembership = new EndFeatureMembership();
70+
var siblingNonFeature = new Namespace();
71+
var mixedFeature = new Feature();
72+
73+
((IContainedRelationship)mixedMembership).OwnedRelatedElement.Add(siblingNonFeature);
74+
((IContainedRelationship)mixedMembership).OwnedRelatedElement.Add(mixedFeature);
75+
76+
Assert.That(mixedMembership.ComputeOwnedMemberFeature(), Is.SameAs(mixedFeature));
77+
78+
// OwnedRelatedElement populated with non-IFeature element(s) only → no IFeature match:
79+
// [1..1] violation, throws IncompleteModelException.
80+
var nonFeatureMembership = new EndFeatureMembership();
81+
var nonFeatureElement = new Namespace();
82+
83+
((IContainedRelationship)nonFeatureMembership).OwnedRelatedElement.Add(nonFeatureElement);
84+
85+
Assert.That(() => nonFeatureMembership.ComputeOwnedMemberFeature(), Throws.TypeOf<IncompleteModelException>());
3686
}
3787
}
3888
}

SysML2.NET/Extend/EndFeatureMembershipExtensions.cs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,8 @@
2121
namespace SysML2.NET.Core.POCO.Core.Features
2222
{
2323
using System;
24-
using System.Collections.Generic;
2524

26-
using SysML2.NET.Core.Root.Namespaces;
27-
using SysML2.NET.Core.POCO.Core.Types;
28-
using SysML2.NET.Core.POCO.Root.Annotations;
29-
using SysML2.NET.Core.POCO.Root.Elements;
30-
using SysML2.NET.Core.POCO.Root.Namespaces;
25+
using SysML2.NET.Extensions;
3126

3227
/// <summary>
3328
/// The <see cref="EndFeatureMembershipExtensions"/> class provides extensions methods for
@@ -44,11 +39,14 @@ internal static class EndFeatureMembershipExtensions
4439
/// <returns>
4540
/// the computed result
4641
/// </returns>
47-
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
4842
internal static IFeature ComputeOwnedMemberFeature(this IEndFeatureMembership endFeatureMembershipSubject)
4943
{
50-
throw new NotSupportedException("Create a GitHub issue when this method is required");
51-
}
44+
if (endFeatureMembershipSubject == null)
45+
{
46+
throw new ArgumentNullException(nameof(endFeatureMembershipSubject));
47+
}
5248

49+
return endFeatureMembershipSubject.OwnedRelatedElement.RequireSingleOfType<IFeature>(nameof(endFeatureMembershipSubject));
50+
}
5351
}
5452
}

0 commit comments

Comments
 (0)