Skip to content

Commit f98dead

Browse files
Fix #100 (#248)
1 parent 30deacc commit f98dead

2 files changed

Lines changed: 55 additions & 16 deletions

File tree

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,72 @@
11
// -------------------------------------------------------------------------------------------------
22
// <copyright file="AttributeUsageExtensionsTestFixture.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;
2626

27-
using SysML2.NET.Core.POCO.Systems.Attributes ;
27+
using SysML2.NET.Core.POCO.Core.Classifiers;
28+
using SysML2.NET.Core.POCO.Core.Features;
29+
using SysML2.NET.Core.POCO.Systems.Attributes;
30+
using SysML2.NET.Extensions;
2831

2932
[TestFixture]
3033
public class AttributeUsageExtensionsTestFixture
3134
{
3235
[Test]
33-
public void ComputeAttributeDefinition_ThrowsNotSupportedException()
36+
public void VerifyComputeAttributeDefinition()
3437
{
35-
Assert.That(() => ((IAttributeUsage)null).ComputeAttributeDefinition(), Throws.TypeOf<NotSupportedException>());
38+
Assert.That(() => ((IAttributeUsage)null).ComputeAttributeDefinition(), Throws.TypeOf<ArgumentNullException>());
39+
40+
var emptySubject = new AttributeUsage();
41+
42+
Assert.That(emptySubject.ComputeAttributeDefinition(), Has.Count.EqualTo(0));
43+
44+
var subject = new AttributeUsage();
45+
var attributeDefinition = new AttributeDefinition();
46+
var bareClassifier = new Classifier();
47+
48+
subject.AssignOwnership(new FeatureTyping { Type = attributeDefinition });
49+
subject.AssignOwnership(new FeatureTyping { Type = bareClassifier });
50+
51+
// Only the IDataType (AttributeDefinition) is returned; bare Classifier is excluded.
52+
Assert.That(subject.ComputeAttributeDefinition(), Is.EquivalentTo(new[] { attributeDefinition }));
3653
}
37-
54+
3855
[Test]
39-
public void ComputeIsReference_ThrowsNotSupportedException()
56+
public void VerifyComputeIsReference()
4057
{
41-
Assert.That(() => ((IAttributeUsage)null).ComputeIsReference(), Throws.TypeOf<NotSupportedException>());
58+
Assert.That(() => ((IAttributeUsage)null).ComputeIsReference(), Throws.TypeOf<ArgumentNullException>());
59+
60+
var emptySubject = new AttributeUsage();
61+
62+
Assert.That(emptySubject.ComputeIsReference(), Is.True);
63+
64+
var populatedSubject = new AttributeUsage();
65+
var attributeDefinition = new AttributeDefinition();
66+
populatedSubject.AssignOwnership(new FeatureTyping { Type = attributeDefinition });
67+
68+
// Always true regardless of subject state — AttributeUsages are always referential.
69+
Assert.That(populatedSubject.ComputeIsReference(), Is.True);
4270
}
4371
}
4472
}

SysML2.NET/Extend/AttributeUsageExtensions.cs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ namespace SysML2.NET.Core.POCO.Systems.Attributes
2222
{
2323
using System;
2424
using System.Collections.Generic;
25+
using System.Linq;
2526

2627
using SysML2.NET.Core.Core.Types;
2728
using SysML2.NET.Core.Root.Namespaces;
@@ -63,16 +64,25 @@ internal static class AttributeUsageExtensions
6364
/// <summary>
6465
/// Computes the derived property.
6566
/// </summary>
67+
/// <remarks>
68+
/// Walks <c>OwnedRelationship</c> → <c>IFeatureTyping</c> → <c>Type</c> directly,
69+
/// filtering to <c>IDataType</c>. The AttributeUsage POCO's explicit-interface
70+
/// <c>IUsage.definition</c> impl delegates to <c>this.attributeDefinition</c>,
71+
/// which would route back into this method → stack overflow. Bypassing the
72+
/// instance property mirrors the technique in
73+
/// <see cref="UsageExtensions.ComputeDefinition" />.
74+
/// </remarks>
6675
/// <param name="attributeUsageSubject">
6776
/// The subject <see cref="IAttributeUsage"/>
6877
/// </param>
6978
/// <returns>
7079
/// the computed result
7180
/// </returns>
72-
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
7381
internal static List<IDataType> ComputeAttributeDefinition(this IAttributeUsage attributeUsageSubject)
7482
{
75-
throw new NotSupportedException("Create a GitHub issue when this method is required");
83+
return attributeUsageSubject == null
84+
? throw new ArgumentNullException(nameof(attributeUsageSubject))
85+
: [..attributeUsageSubject.OwnedRelationship.OfType<IFeatureTyping>().Select(featureTyping => featureTyping.Type).OfType<IDataType>()];
7686
}
7787

7888
/// <summary>
@@ -84,10 +94,11 @@ internal static List<IDataType> ComputeAttributeDefinition(this IAttributeUsage
8494
/// <returns>
8595
/// the computed result
8696
/// </returns>
87-
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
8897
internal static bool ComputeIsReference(this IAttributeUsage attributeUsageSubject)
8998
{
90-
throw new NotSupportedException("Create a GitHub issue when this method is required");
99+
return attributeUsageSubject == null
100+
? throw new ArgumentNullException(nameof(attributeUsageSubject))
101+
: true;
91102
}
92103

93104
}

0 commit comments

Comments
 (0)