Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ Auto-generated DTOs use structured namespaces reflecting the KerML/SysML package

## Key Conventions

- **Paths are ALWAYS repo-relative — NEVER absolute.** This rule applies to every path the agent writes anywhere: code comments, XML doc `<see cref="…"/>` and prose, source-string citations, error/log messages, commit messages, PR bodies, GitHub issue bodies, `.team-notes/` spec files, plan files, skill prompts and agent briefs (e.g. say `SysML2.NET/Extend/FooExtensions.cs`, NOT `C:\CODE\SysML2.NET\SysML2.NET\Extend\FooExtensions.cs` and NOT `/c/CODE/SysML2.NET/...`). Use forward slashes. Reason: absolute paths are user-/machine-specific and leak the local filesystem into the repo and into communication with other contributors — they break for anyone else, get stale on rename/move, and are noisy. The ONLY exception is the `Read` / `Edit` / `Write` tool `file_path` parameter, which the tool implementation requires to be absolute — those tool arguments are not user-visible artifacts. Everything you author as content must be repo-relative.
- Commit messages use prefix tags: `[Add]`, `[Update]`, `[Remove]`, `[Fix]` — except for issue-fixing commits produced by `/implement-extensions` and `/implement-extensions-batch`, which use the canonical short form `Fix #<n>` (single issue) or `Fix #<n1> #<n2> …` (batch) so GitHub auto-closes the issues on merge.
- Main branch: `master`. Development branch: `development`. **All feature work targets `development`** via PR; `master` is downstream only.
- CI: GitHub Actions (`CodeQuality.yml`) — builds, tests, and runs SonarQube analysis
Expand Down
46 changes: 36 additions & 10 deletions SysML2.NET.Tests/Extend/RenderingDefinitionExtensionsTestFixture.cs
Original file line number Diff line number Diff line change
@@ -1,38 +1,64 @@
// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// <copyright file="RenderingDefinitionExtensionsTestFixture.cs" company="Starion Group S.A.">
//
//
// 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.
//
//
// </copyright>
// ------------------------------------------------------------------------------------------------

namespace SysML2.NET.Tests.Extend
{
using System;

using NUnit.Framework;


using SysML2.NET.Core.POCO.Core.Types;
using SysML2.NET.Core.POCO.Systems.Parts;
using SysML2.NET.Core.POCO.Systems.Views;
using SysML2.NET.Extensions;

[TestFixture]
public class RenderingDefinitionExtensionsTestFixture
{
[Test]
public void ComputeRendering_ThrowsNotSupportedException()
public void VerifyComputeRendering()
{
Assert.That(() => ((IRenderingDefinition)null).ComputeRendering(), Throws.TypeOf<NotSupportedException>());
Assert.That(() => ((IRenderingDefinition)null).ComputeRendering(), Throws.TypeOf<ArgumentNullException>());

var renderingDefinition = new RenderingDefinition();

// Empty: no usages wired → empty result.
Assert.That(renderingDefinition.ComputeRendering(), Is.Empty);

// Discrimination: PartUsage in usage (not IRenderingUsage) → excluded.
var partUsage = new PartUsage();
renderingDefinition.AssignOwnership(new FeatureMembership(), partUsage);

Assert.That(renderingDefinition.ComputeRendering(), Is.Empty);

// Positive: RenderingUsage wired via FeatureMembership → appears in usage → included.
var renderingUsage = new RenderingUsage();
renderingDefinition.AssignOwnership(new FeatureMembership(), renderingUsage);

Assert.That(renderingDefinition.ComputeRendering(), Is.EqualTo([renderingUsage]));

// Multiple: second RenderingUsage also returned.
var renderingUsage2 = new RenderingUsage();
renderingDefinition.AssignOwnership(new FeatureMembership(), renderingUsage2);

Assert.That(renderingDefinition.ComputeRendering(), Is.EqualTo([renderingUsage, renderingUsage2]));
}
}
}
49 changes: 39 additions & 10 deletions SysML2.NET.Tests/Extend/RenderingUsageExtensionsTestFixture.cs
Original file line number Diff line number Diff line change
@@ -1,38 +1,67 @@
// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// <copyright file="RenderingUsageExtensionsTestFixture.cs" company="Starion Group S.A.">
//
//
// 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.
//
//
// </copyright>
// ------------------------------------------------------------------------------------------------

namespace SysML2.NET.Tests.Extend
{
using System;

using NUnit.Framework;


using SysML2.NET.Core.POCO.Core.Features;
using SysML2.NET.Core.POCO.Systems.Parts;
using SysML2.NET.Core.POCO.Systems.Views;
using SysML2.NET.Extensions;

[TestFixture]
public class RenderingUsageExtensionsTestFixture
{
[Test]
public void ComputeRenderingDefinition_ThrowsNotSupportedException()
public void VerifyComputeRenderingDefinition()
{
Assert.That(() => ((IRenderingUsage)null).ComputeRenderingDefinition(), Throws.TypeOf<NotSupportedException>());
Assert.That(() => ((IRenderingUsage)null).ComputeRenderingDefinition(), Throws.TypeOf<ArgumentNullException>());

var renderingUsage = new RenderingUsage();

// Empty: no OwnedRelationship → null.
Assert.That(renderingUsage.ComputeRenderingDefinition(), Is.Null);

// Negative: FeatureTyping whose Type is a non-RenderingDefinition (PartDefinition) → null.
var partDefinition = new PartDefinition();
var typingToPartDefinition = new FeatureTyping { Type = partDefinition };
renderingUsage.AssignOwnership(typingToPartDefinition);

Assert.That(renderingUsage.ComputeRenderingDefinition(), Is.Null);

// Positive: FeatureTyping whose Type is a RenderingDefinition → returned.
var renderingDefinition = new RenderingDefinition();
var typingToRenderingDefinition = new FeatureTyping { Type = renderingDefinition };
renderingUsage.AssignOwnership(typingToRenderingDefinition);

Assert.That(renderingUsage.ComputeRenderingDefinition(), Is.SameAs(renderingDefinition));

// Multiple: second RenderingDefinition typing present; FirstOrDefault returns the first match.
var renderingDefinition2 = new RenderingDefinition();
var typingToRenderingDefinition2 = new FeatureTyping { Type = renderingDefinition2 };
renderingUsage.AssignOwnership(typingToRenderingDefinition2);

Assert.That(renderingUsage.ComputeRenderingDefinition(), Is.SameAs(renderingDefinition));
}
}
}
144 changes: 125 additions & 19 deletions SysML2.NET.Tests/Extend/ViewDefinitionExtensionsTestFixture.cs
Original file line number Diff line number Diff line change
@@ -1,56 +1,162 @@
// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// <copyright file="ViewDefinitionExtensionsTestFixture.cs" company="Starion Group S.A.">
//
//
// 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.
//
//
// </copyright>
// ------------------------------------------------------------------------------------------------

namespace SysML2.NET.Tests.Extend
{
using System;

using NUnit.Framework;


using SysML2.NET.Core.POCO.Core.Features;
using SysML2.NET.Core.POCO.Core.Types;
using SysML2.NET.Core.POCO.Kernel.Functions;
using SysML2.NET.Core.POCO.Kernel.Packages;
using SysML2.NET.Core.POCO.Root.Namespaces;
using SysML2.NET.Core.POCO.Systems.Parts;
using SysML2.NET.Core.POCO.Systems.Requirements;
using SysML2.NET.Core.POCO.Systems.Views;
using SysML2.NET.Extensions;

[TestFixture]
public class ViewDefinitionExtensionsTestFixture
{
[Test]
public void ComputeSatisfiedViewpoint_ThrowsNotSupportedException()
public void VerifyComputeSatisfiedViewpoint()
{
Assert.That(() => ((IViewDefinition)null).ComputeSatisfiedViewpoint(), Throws.TypeOf<NotSupportedException>());
Assert.That(() => ((IViewDefinition)null).ComputeSatisfiedViewpoint(), Throws.TypeOf<ArgumentNullException>());

var viewDefinition = new ViewDefinition();

// Empty: no ownedRequirement → empty result.
Assert.That(viewDefinition.ComputeSatisfiedViewpoint(), Is.Empty);

// Discrimination: plain RequirementUsage (not IViewpointUsage) → excluded.
var plainRequirement = new RequirementUsage { IsComposite = true };
viewDefinition.AssignOwnership(new FeatureMembership(), plainRequirement);

Assert.That(viewDefinition.ComputeSatisfiedViewpoint(), Is.Empty);

// Predicate discrimination: ViewpointUsage with IsComposite = false → excluded.
var nonCompositeViewpoint = new ViewpointUsage { IsComposite = false };
viewDefinition.AssignOwnership(new FeatureMembership(), nonCompositeViewpoint);

Assert.That(viewDefinition.ComputeSatisfiedViewpoint(), Is.Empty);

// Positive: composite ViewpointUsage → included.
var compositeViewpoint = new ViewpointUsage { IsComposite = true };
viewDefinition.AssignOwnership(new FeatureMembership(), compositeViewpoint);

Assert.That(viewDefinition.ComputeSatisfiedViewpoint(), Is.EqualTo([compositeViewpoint]));

// Multiple: second composite ViewpointUsage also returned in iteration order.
var compositeViewpoint2 = new ViewpointUsage { IsComposite = true };
viewDefinition.AssignOwnership(new FeatureMembership(), compositeViewpoint2);

Assert.That(viewDefinition.ComputeSatisfiedViewpoint(), Is.EqualTo([compositeViewpoint, compositeViewpoint2]));
}

[Test]
public void ComputeView_ThrowsNotSupportedException()
public void VerifyComputeView()
{
Assert.That(() => ((IViewDefinition)null).ComputeView(), Throws.TypeOf<NotSupportedException>());
Assert.That(() => ((IViewDefinition)null).ComputeView(), Throws.TypeOf<ArgumentNullException>());

var viewDefinition = new ViewDefinition();

// Empty: no usages → empty result.
Assert.That(viewDefinition.ComputeView(), Is.Empty);

// Discrimination: PartUsage in usage (not IViewUsage) → excluded.
var partUsage = new PartUsage();
viewDefinition.AssignOwnership(new FeatureMembership(), partUsage);

Assert.That(viewDefinition.ComputeView(), Is.Empty);

// Positive: ViewUsage → included.
var viewUsage = new ViewUsage();
viewDefinition.AssignOwnership(new FeatureMembership(), viewUsage);

Assert.That(viewDefinition.ComputeView(), Is.EqualTo([viewUsage]));

// Multiple: second ViewUsage also returned.
var viewUsage2 = new ViewUsage();
viewDefinition.AssignOwnership(new FeatureMembership(), viewUsage2);

Assert.That(viewDefinition.ComputeView(), Is.EqualTo([viewUsage, viewUsage2]));
}

[Test]
public void ComputeViewCondition_ThrowsNotSupportedException()
public void VerifyComputeViewCondition()
{
Assert.That(() => ((IViewDefinition)null).ComputeViewCondition(), Throws.TypeOf<NotSupportedException>());
Assert.That(() => ((IViewDefinition)null).ComputeViewCondition(), Throws.TypeOf<ArgumentNullException>());

var viewDefinition = new ViewDefinition();

// Empty: no ownedMembership → empty result.
Assert.That(viewDefinition.ComputeViewCondition(), Is.Empty);

// Discrimination: non-ElementFilterMembership in ownedMembership → excluded.
var plainFeature = new Feature();
var plainMembership = new OwningMembership();
viewDefinition.AssignOwnership(plainMembership, plainFeature);

Assert.That(viewDefinition.ComputeViewCondition(), Is.Empty);

// Positive: ElementFilterMembership with a concrete IExpression → condition included.
var filterCondition = new BooleanExpression();
var filterMembership = new ElementFilterMembership();
viewDefinition.AssignOwnership(filterMembership, filterCondition);

Assert.That(viewDefinition.ComputeViewCondition(), Is.EqualTo([filterCondition]));
}

[Test]
public void ComputeViewRendering_ThrowsNotSupportedException()
public void VerifyComputeViewRendering()
{
Assert.That(() => ((IViewDefinition)null).ComputeViewRendering(), Throws.TypeOf<NotSupportedException>());
Assert.That(() => ((IViewDefinition)null).ComputeViewRendering(), Throws.TypeOf<ArgumentNullException>());

var viewDefinition = new ViewDefinition();

// Empty: no featureMembership → null.
Assert.That(viewDefinition.ComputeViewRendering(), Is.Null);

// Discrimination: non-ViewRenderingMembership featureMembership → null.
var plainFeature = new Feature();
var plainFeatureMembership = new FeatureMembership();
viewDefinition.AssignOwnership(plainFeatureMembership, plainFeature);

Assert.That(viewDefinition.ComputeViewRendering(), Is.Null);

// Positive: ViewRenderingMembership whose ownedRendering is a RenderingUsage (no
// ownedReferenceSubsetting) → referencedRendering == ownedRendering → returned.
var renderingUsage = new RenderingUsage();
var viewRenderingMembership = new ViewRenderingMembership();
viewDefinition.AssignOwnership(viewRenderingMembership, renderingUsage);

Assert.That(viewDefinition.ComputeViewRendering(), Is.SameAs(renderingUsage));

// Multiple ViewRenderingMemberships: the first one wins (renderings->first() semantics).
var renderingUsage2 = new RenderingUsage();
var viewRenderingMembership2 = new ViewRenderingMembership();
viewDefinition.AssignOwnership(viewRenderingMembership2, renderingUsage2);

Assert.That(viewDefinition.ComputeViewRendering(), Is.SameAs(renderingUsage));
}
}
}
Loading
Loading