From 2f6cfd2c36f2b9250e185d014c38eeae40206a8c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jul 2026 09:53:02 +0000 Subject: [PATCH 1/2] Bump the nuget-dependencies group with 2 updates Bumps demaconsulting.pandoctool from 3.10.0 to 3.10.1 Bumps SonarAnalyzer.CSharp from 10.29.0.143774 to 10.30.0.144632 --- updated-dependencies: - dependency-name: demaconsulting.pandoctool dependency-version: 3.10.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nuget-dependencies - dependency-name: SonarAnalyzer.CSharp dependency-version: 10.30.0.144632 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nuget-dependencies - dependency-name: SonarAnalyzer.CSharp dependency-version: 10.30.0.144632 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nuget-dependencies - dependency-name: SonarAnalyzer.CSharp dependency-version: 10.30.0.144632 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nuget-dependencies - dependency-name: SonarAnalyzer.CSharp dependency-version: 10.30.0.144632 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nuget-dependencies ... Signed-off-by: dependabot[bot] --- .config/dotnet-tools.json | 2 +- .../DemaConsulting.SysML2Tools.Core.csproj | 2 +- .../DemaConsulting.SysML2Tools.Language.csproj | 2 +- .../DemaConsulting.SysML2Tools.Stdlib.csproj | 2 +- .../DemaConsulting.SysML2Tools.Tool.csproj | 2 +- .../DemaConsulting.SysML2Tools.Tests.csproj | 2 +- .../DemaConsulting.SysML2Tools.Tool.Tests.csproj | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 337f9eca..bfd740ee 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -9,7 +9,7 @@ ] }, "demaconsulting.pandoctool": { - "version": "3.10.0", + "version": "3.10.1", "commands": [ "pandoc" ] diff --git a/src/DemaConsulting.SysML2Tools.Core/DemaConsulting.SysML2Tools.Core.csproj b/src/DemaConsulting.SysML2Tools.Core/DemaConsulting.SysML2Tools.Core.csproj index 63464ffe..186c354b 100644 --- a/src/DemaConsulting.SysML2Tools.Core/DemaConsulting.SysML2Tools.Core.csproj +++ b/src/DemaConsulting.SysML2Tools.Core/DemaConsulting.SysML2Tools.Core.csproj @@ -86,7 +86,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/DemaConsulting.SysML2Tools.Language/DemaConsulting.SysML2Tools.Language.csproj b/src/DemaConsulting.SysML2Tools.Language/DemaConsulting.SysML2Tools.Language.csproj index 2ee5ec6f..a28c1fd3 100644 --- a/src/DemaConsulting.SysML2Tools.Language/DemaConsulting.SysML2Tools.Language.csproj +++ b/src/DemaConsulting.SysML2Tools.Language/DemaConsulting.SysML2Tools.Language.csproj @@ -86,7 +86,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/DemaConsulting.SysML2Tools.Stdlib/DemaConsulting.SysML2Tools.Stdlib.csproj b/src/DemaConsulting.SysML2Tools.Stdlib/DemaConsulting.SysML2Tools.Stdlib.csproj index b8cbfec3..6ff6bd87 100644 --- a/src/DemaConsulting.SysML2Tools.Stdlib/DemaConsulting.SysML2Tools.Stdlib.csproj +++ b/src/DemaConsulting.SysML2Tools.Stdlib/DemaConsulting.SysML2Tools.Stdlib.csproj @@ -96,7 +96,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/DemaConsulting.SysML2Tools.Tool/DemaConsulting.SysML2Tools.Tool.csproj b/src/DemaConsulting.SysML2Tools.Tool/DemaConsulting.SysML2Tools.Tool.csproj index 2f723862..df04876b 100644 --- a/src/DemaConsulting.SysML2Tools.Tool/DemaConsulting.SysML2Tools.Tool.csproj +++ b/src/DemaConsulting.SysML2Tools.Tool/DemaConsulting.SysML2Tools.Tool.csproj @@ -81,7 +81,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/DemaConsulting.SysML2Tools.Tests/DemaConsulting.SysML2Tools.Tests.csproj b/test/DemaConsulting.SysML2Tools.Tests/DemaConsulting.SysML2Tools.Tests.csproj index 870dd533..8e471560 100644 --- a/test/DemaConsulting.SysML2Tools.Tests/DemaConsulting.SysML2Tools.Tests.csproj +++ b/test/DemaConsulting.SysML2Tools.Tests/DemaConsulting.SysML2Tools.Tests.csproj @@ -45,7 +45,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/DemaConsulting.SysML2Tools.Tool.Tests/DemaConsulting.SysML2Tools.Tool.Tests.csproj b/test/DemaConsulting.SysML2Tools.Tool.Tests/DemaConsulting.SysML2Tools.Tool.Tests.csproj index e4958acd..8a3173a0 100644 --- a/test/DemaConsulting.SysML2Tools.Tool.Tests/DemaConsulting.SysML2Tools.Tool.Tests.csproj +++ b/test/DemaConsulting.SysML2Tools.Tool.Tests/DemaConsulting.SysML2Tools.Tool.Tests.csproj @@ -54,7 +54,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From c1fb65a9ac8865a7c76de7a5d0b7ef9a88d45dc6 Mon Sep 17 00:00:00 2001 From: Malcolm Nixon Date: Mon, 27 Jul 2026 11:48:32 -0400 Subject: [PATCH 2/2] Remove redundant null-forgiving operators (S8969) SonarAnalyzer.CSharp 10.30 added rule S8969, which flags null-forgiving operators the compiler already knows are unnecessary. These pre-existing operators were failing the dotnet format lint phase after the analyzer bump. Removed the redundant operators via SonarAnalyzer's code fix. In GeneralViewLayoutStrategy.TryResolveQualified, annotated the out parameter with [MaybeNullWhen(false)] instead of using a null-forgiving operator, which satisfies both S8969 and CS8601 nullable analysis. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Internal/GeneralViewLayoutStrategy.cs | 5 +- .../FilterExpressionEvaluatorTests.cs | 2 +- .../Filtering/FilterExpressionParserTests.cs | 4 +- .../Layout/GeneralViewLayoutStrategyTests.cs | 14 +- .../InterconnectionViewLayoutStrategyTests.cs | 2 +- .../StateTransitionViewLayoutStrategyTests.cs | 2 +- .../Parser/OmgModelsTests.cs | 14 +- .../Query/QueryRenderingTests.cs | 8 +- .../Rendering/DynamicViewSynthesizerTests.cs | 44 ++-- .../Semantic/AstBuilderMetadataTests.cs | 24 +- .../Semantic/WorkspaceLoaderTests.cs | 246 +++++++++--------- .../Export/ExportRenderingTests.cs | 14 +- .../Query/QuerySubsystemTests.cs | 2 +- .../Query/QueryVerbsTests.cs | 2 +- 14 files changed, 192 insertions(+), 191 deletions(-) diff --git a/src/DemaConsulting.SysML2Tools.Core/Layout/Internal/GeneralViewLayoutStrategy.cs b/src/DemaConsulting.SysML2Tools.Core/Layout/Internal/GeneralViewLayoutStrategy.cs index 6bdb9169..8d1a5420 100644 --- a/src/DemaConsulting.SysML2Tools.Core/Layout/Internal/GeneralViewLayoutStrategy.cs +++ b/src/DemaConsulting.SysML2Tools.Core/Layout/Internal/GeneralViewLayoutStrategy.cs @@ -2,6 +2,7 @@ // Copyright (c) DemaConsulting. All rights reserved. // +using System.Diagnostics.CodeAnalysis; using DemaConsulting.Rendering; using DemaConsulting.Rendering.Abstractions; using DemaConsulting.Rendering.Layout; @@ -1076,7 +1077,7 @@ private static bool TryResolveQualified( string reference, HashSet byQualified, Dictionary bySimple, - out string qualified) + [MaybeNullWhen(false)] out string qualified) { if (byQualified.Contains(reference)) { @@ -1086,7 +1087,7 @@ private static bool TryResolveQualified( var sep = reference.LastIndexOf("::", StringComparison.Ordinal); var simple = sep >= 0 ? reference[(sep + 2)..] : reference; - return bySimple.TryGetValue(simple, out qualified!); + return bySimple.TryGetValue(simple, out qualified); } /// diff --git a/test/DemaConsulting.SysML2Tools.Tests/Filtering/FilterExpressionEvaluatorTests.cs b/test/DemaConsulting.SysML2Tools.Tests/Filtering/FilterExpressionEvaluatorTests.cs index 16f72a64..d7a94245 100644 --- a/test/DemaConsulting.SysML2Tools.Tests/Filtering/FilterExpressionEvaluatorTests.cs +++ b/test/DemaConsulting.SysML2Tools.Tests/Filtering/FilterExpressionEvaluatorTests.cs @@ -23,7 +23,7 @@ private static async Task LoadAsync(string source) var (stdlibTable, _) = StdlibProvider.GetSymbolTable(); var result = await WorkspaceLoader.LoadAsync([tempFile], stdlibTable); Assert.NotNull(result.Workspace); - return result.Workspace!; + return result.Workspace; } finally { diff --git a/test/DemaConsulting.SysML2Tools.Tests/Filtering/FilterExpressionParserTests.cs b/test/DemaConsulting.SysML2Tools.Tests/Filtering/FilterExpressionParserTests.cs index 623668aa..b98d1fe4 100644 --- a/test/DemaConsulting.SysML2Tools.Tests/Filtering/FilterExpressionParserTests.cs +++ b/test/DemaConsulting.SysML2Tools.Tests/Filtering/FilterExpressionParserTests.cs @@ -484,8 +484,8 @@ public void Parse_RoundTrip_PrettyPrintedTextReparsesToEquivalentTree(string exp var first = FilterExpressionParser.Parse(expressionText); Assert.NotNull(first.Expression); - var printed = first.Expression!.ToString(); - var second = FilterExpressionParser.Parse(printed!); + var printed = first.Expression.ToString(); + var second = FilterExpressionParser.Parse(printed); Assert.NotNull(second.Expression); Assert.Equal(first.Expression, second.Expression); diff --git a/test/DemaConsulting.SysML2Tools.Tests/Layout/GeneralViewLayoutStrategyTests.cs b/test/DemaConsulting.SysML2Tools.Tests/Layout/GeneralViewLayoutStrategyTests.cs index 3c2bd02d..aaa3e526 100644 --- a/test/DemaConsulting.SysML2Tools.Tests/Layout/GeneralViewLayoutStrategyTests.cs +++ b/test/DemaConsulting.SysML2Tools.Tests/Layout/GeneralViewLayoutStrategyTests.cs @@ -164,7 +164,7 @@ public void GeneralViewLayoutStrategy_BuildLayout_PackagedDefinitions_ProducesFo // Assert: a folder-shaped box exists carrying the package keyword var folder = CollectBoxes(layout.Nodes).FirstOrDefault(b => b.Shape == BoxShape.Folder); Assert.NotNull(folder); - Assert.Equal("package", folder!.Keyword); + Assert.Equal("package", folder.Keyword); Assert.Equal("Sys", folder.Label); } @@ -431,7 +431,7 @@ public void GeneralViewLayoutStrategy_BuildLayout_Subclassification_ProducesEdge // Assert: at least one orthogonal line with an open arrowhead at the supertype end var line = CollectLines(layout.Nodes).FirstOrDefault(); Assert.NotNull(line); - Assert.Equal(EndMarkerStyle.HollowTriangle, line!.TargetEnd); + Assert.Equal(EndMarkerStyle.HollowTriangle, line.TargetEnd); Assert.True(line.Waypoints.Count >= 2); } @@ -705,7 +705,7 @@ public void GeneralViewLayoutStrategy_BuildLayout_AttributeTyping_ProducesDashed var typingEdge = CollectLines(layout.Nodes) .FirstOrDefault(l => l.LineStyle == LineStyle.Dashed && l.TargetEnd == EndMarkerStyle.OpenChevron); Assert.NotNull(typingEdge); - Assert.True(typingEdge!.Waypoints.Count >= 2); + Assert.True(typingEdge.Waypoints.Count >= 2); // Assert: attribute typing is a dependency, not composition — no membership diamond is drawn. var diamondEdge = CollectLines(layout.Nodes) @@ -762,7 +762,7 @@ public void GeneralViewLayoutStrategy_BuildLayout_BareNameRedefinition_ProducesH var redefinitionEdge = CollectLines(layout.Nodes) .FirstOrDefault(l => l.TargetEnd == EndMarkerStyle.HollowTriangleCrossbar); Assert.NotNull(redefinitionEdge); - Assert.Equal(LineStyle.Solid, redefinitionEdge!.LineStyle); + Assert.Equal(LineStyle.Solid, redefinitionEdge.LineStyle); } /// @@ -1700,7 +1700,7 @@ public async Task GeneralViewLayoutStrategy_BuildLayout_DroneGalleryModel_Render var (stdlibTable, _) = StdlibProvider.GetSymbolTable(); var result = await WorkspaceLoader.LoadAsync([modelPath], stdlibTable); Assert.NotNull(result.Workspace); - var workspace = result.Workspace!; + var workspace = result.Workspace; const string viewQualifiedName = "QuadcopterDrone::DroneGeneralView"; var viewNode = Assert.IsType(workspace.Declarations[viewQualifiedName]); @@ -1801,7 +1801,7 @@ public async Task GeneralViewLayoutStrategy_BuildLayout_OmgSafetyFeatureViewsFix var (stdlibTable, _) = StdlibProvider.GetSymbolTable(); var result = await WorkspaceLoader.LoadAsync([fixturePath], stdlibTable); Assert.NotNull(result.Workspace); - var workspace = result.Workspace!; + var workspace = result.Workspace; const string viewQualifiedName = "'11b-Safety and Security Feaure Views'::Views::vehicleMandatorySafetyFeatureViewStandalone"; @@ -2039,7 +2039,7 @@ part def Drone { var (stdlibTable, _) = StdlibProvider.GetSymbolTable(); var result = await WorkspaceLoader.LoadAsync([tempFile], stdlibTable); Assert.NotNull(result.Workspace); - var workspace = result.Workspace!; + var workspace = result.Workspace; var strategy = new GeneralViewLayoutStrategy(); var options = new RenderOptions(Themes.Light); diff --git a/test/DemaConsulting.SysML2Tools.Tests/Layout/InterconnectionViewLayoutStrategyTests.cs b/test/DemaConsulting.SysML2Tools.Tests/Layout/InterconnectionViewLayoutStrategyTests.cs index 634f387b..bf654193 100644 --- a/test/DemaConsulting.SysML2Tools.Tests/Layout/InterconnectionViewLayoutStrategyTests.cs +++ b/test/DemaConsulting.SysML2Tools.Tests/Layout/InterconnectionViewLayoutStrategyTests.cs @@ -216,7 +216,7 @@ public void InterconnectionView_BuildLayout_PartWithPorts_PortsNeverOverlapBoxTi Assert.NotNull(owningBox); Assert.True( - port.CentreY >= owningBox!.Y + titleArea, + port.CentreY >= owningBox.Y + titleArea, $"port at ({port.CentreX}, {port.CentreY}) overlaps the title area of its box (Y={owningBox.Y}, titleArea={titleArea})"); } } diff --git a/test/DemaConsulting.SysML2Tools.Tests/Layout/StateTransitionViewLayoutStrategyTests.cs b/test/DemaConsulting.SysML2Tools.Tests/Layout/StateTransitionViewLayoutStrategyTests.cs index 1465df22..18a824ee 100644 --- a/test/DemaConsulting.SysML2Tools.Tests/Layout/StateTransitionViewLayoutStrategyTests.cs +++ b/test/DemaConsulting.SysML2Tools.Tests/Layout/StateTransitionViewLayoutStrategyTests.cs @@ -177,7 +177,7 @@ public void StateTransitionView_BuildLayout_TransitionEdge_HasOpenArrowhead() var transitionLine = layout.Nodes.OfType() .FirstOrDefault(l => l.MidpointLabel == "[g]"); Assert.NotNull(transitionLine); - Assert.Equal(EndMarkerStyle.OpenChevron, transitionLine!.TargetEnd); + Assert.Equal(EndMarkerStyle.OpenChevron, transitionLine.TargetEnd); } /// diff --git a/test/DemaConsulting.SysML2Tools.Tests/Parser/OmgModelsTests.cs b/test/DemaConsulting.SysML2Tools.Tests/Parser/OmgModelsTests.cs index a3465c48..2a7f87b5 100644 --- a/test/DemaConsulting.SysML2Tools.Tests/Parser/OmgModelsTests.cs +++ b/test/DemaConsulting.SysML2Tools.Tests/Parser/OmgModelsTests.cs @@ -297,7 +297,7 @@ public async Task ControlNode_OmgCorpusFixture_ResolvesForkJoinDecisionMerge() // DecisionExample.sysml: an anonymous decide with two guarded successions, plus a named // merge that the decide's default-path action succession eventually rejoins. - var chargeBattery = (SysmlDefinitionNode)result.Workspace!.Declarations["'Decision Example'::ChargeBattery"]; + var chargeBattery = (SysmlDefinitionNode)result.Workspace.Declarations["'Decision Example'::ChargeBattery"]; var decide = Assert.Single( chargeBattery.Children.OfType(), f => f.FeatureKeyword == "decide"); Assert.NotNull(decide.Name); @@ -324,7 +324,7 @@ public async Task ControlNode_OmgCorpusFixture_ResolvesForkJoinDecisionMerge() Assert.Contains(chargeBatteryTransitions, t => t.Source == "monitor" && t.Target == decide.Name); // ControlNodeTest.sysml: fully named fork/join/merge — the richest, most reliable fixture. - var controlNodeTest = (SysmlDefinitionNode)result.Workspace!.Declarations["ControlNodeTest"]; + var controlNodeTest = (SysmlDefinitionNode)result.Workspace.Declarations["ControlNodeTest"]; var controlFeatures = controlNodeTest.Children.OfType().ToList(); Assert.Contains(controlFeatures, f => f.FeatureKeyword == "join" && f.Name == "J"); Assert.Contains(controlFeatures, f => f.FeatureKeyword == "fork" && f.Name == "F"); @@ -382,7 +382,7 @@ public async Task Enumeration_OmgCorpusFixtures_CaptureAllLiteralForms() // Redefinition-body form (each literal redefines "code"/"color" attributes via `:>>`). var classificationKind = - (SysmlDefinitionNode)result.Workspace!.Declarations["'Enumeration Definitions-2'::ClassificationKind"]; + (SysmlDefinitionNode)result.Workspace.Declarations["'Enumeration Definitions-2'::ClassificationKind"]; var classificationValues = classificationKind.Children .OfType() .Where(f => f.FeatureKeyword == "enum value") @@ -393,7 +393,7 @@ public async Task Enumeration_OmgCorpusFixtures_CaptureAllLiteralForms() // Value-assignment form (`A = 4.0;`) — the assigned value expression is not parsed, only // the literal's own name, an accepted minimal-capture gap. var gradePoints = - (SysmlDefinitionNode)result.Workspace!.Declarations["'Enumeration Definitions-2'::GradePoints"]; + (SysmlDefinitionNode)result.Workspace.Declarations["'Enumeration Definitions-2'::GradePoints"]; var gradeValues = gradePoints.Children .OfType() .Where(f => f.FeatureKeyword == "enum value") @@ -440,7 +440,7 @@ public async Task Requirement_OmgCorpusFixtures_CaptureSubjectAndConstraints() // VehicleMassLimitationRequirement (a requirement def specializing another) has subject + // assume constraint. var vehicleMassLimitation = - (SysmlDefinitionNode)result.Workspace!.Declarations[ + (SysmlDefinitionNode)result.Workspace.Declarations[ "'Requirement Definitions'::VehicleMassLimitationRequirement"]; var subject = Assert.Single( vehicleMassLimitation.Children.OfType(), f => f.FeatureKeyword == "subject"); @@ -453,7 +453,7 @@ public async Task Requirement_OmgCorpusFixtures_CaptureSubjectAndConstraints() // RequirementUsages.sysml: fullVehicleMassLimit is a requirement *usage* specializing // VehicleMassLimitationRequirement, with its own subject + assume constraint body. var fullVehicleMassLimit = - (SysmlFeatureNode)result.Workspace!.Declarations["'Requirement Usages'::fullVehicleMassLimit"]; + (SysmlFeatureNode)result.Workspace.Declarations["'Requirement Usages'::fullVehicleMassLimit"]; var usageSubject = Assert.Single( fullVehicleMassLimit.Children.OfType(), f => f.FeatureKeyword == "subject"); Assert.Equal("vehicle", usageSubject.Name); @@ -498,7 +498,7 @@ public async Task CommentAndDocumentation_OmgCorpusFixtures_CaptureAnnotations() Assert.Contains(partDefC.Annotations, a => a.Kind == SysmlAnnotationKind.Comment); var automobileWithDoc = - (SysmlDefinitionNode)result.Workspace!.Declarations["'Documentation Example'::Automobile"]; + (SysmlDefinitionNode)result.Workspace.Declarations["'Documentation Example'::Automobile"]; Assert.Contains(automobileWithDoc.Annotations, a => a.Kind == SysmlAnnotationKind.Documentation); } } diff --git a/test/DemaConsulting.SysML2Tools.Tests/Query/QueryRenderingTests.cs b/test/DemaConsulting.SysML2Tools.Tests/Query/QueryRenderingTests.cs index 0a848cfc..2d617354 100644 --- a/test/DemaConsulting.SysML2Tools.Tests/Query/QueryRenderingTests.cs +++ b/test/DemaConsulting.SysML2Tools.Tests/Query/QueryRenderingTests.cs @@ -314,7 +314,7 @@ public void RenderJson_RoundTrips_PreservesShape() var deserialized = JsonSerializer.Deserialize(json, QueryResultSerializerContext.Default.QueryResult); Assert.NotNull(deserialized); - Assert.Equal("uses", deserialized!.Verb); + Assert.Equal("uses", deserialized.Verb); Assert.Equal("Model::Foo", deserialized.Element); Assert.Single(deserialized.Entries); Assert.Equal("Model::Bar", deserialized.Entries[0].QualifiedName); @@ -341,7 +341,7 @@ public void RenderJson_UnorderedEntries_SortsByQualifiedNameOrdinal() var deserialized = JsonSerializer.Deserialize(json, QueryResultSerializerContext.Default.QueryResult); Assert.NotNull(deserialized); - Assert.Equal("Model::Apple", deserialized!.Entries[0].QualifiedName); + Assert.Equal("Model::Apple", deserialized.Entries[0].QualifiedName); Assert.Equal("Model::Zebra", deserialized.Entries[1].QualifiedName); } @@ -368,7 +368,7 @@ public void RenderJson_DependenciesVerb_IncludesDirectionField() Assert.NotNull(deserialized); Assert.Contains("\"Direction\"", json); - Assert.Equal(QueryEntryDirection.Incoming, deserialized!.Entries[0].Direction); + Assert.Equal(QueryEntryDirection.Incoming, deserialized.Entries[0].Direction); Assert.Equal(QueryEntryDirection.Outgoing, deserialized.Entries[1].Direction); } @@ -402,7 +402,7 @@ public void RenderJson_DependenciesVerb_NamesRemainFullyQualified() var deserialized = JsonSerializer.Deserialize(json, QueryResultSerializerContext.Default.QueryResult); Assert.NotNull(deserialized); - Assert.Equal("Model::Car", deserialized!.Element); + Assert.Equal("Model::Car", deserialized.Element); Assert.Contains(deserialized.Entries, e => e.QualifiedName == "Model::Vehicle"); Assert.Contains(deserialized.Entries, e => e.QualifiedName == "Model::Truck"); Assert.Contains("Model::Vehicle", json); diff --git a/test/DemaConsulting.SysML2Tools.Tests/Rendering/DynamicViewSynthesizerTests.cs b/test/DemaConsulting.SysML2Tools.Tests/Rendering/DynamicViewSynthesizerTests.cs index 71aa83e3..f82d0e45 100644 --- a/test/DemaConsulting.SysML2Tools.Tests/Rendering/DynamicViewSynthesizerTests.cs +++ b/test/DemaConsulting.SysML2Tools.Tests/Rendering/DynamicViewSynthesizerTests.cs @@ -31,7 +31,7 @@ public void Synthesize_GeneralKind_ResolvableTarget_Succeeds() Assert.Null(diagnostic); Assert.NotNull(viewNode); - Assert.Equal("asGeneralDiagram", viewNode!.RenderTargetName); + Assert.Equal("asGeneralDiagram", viewNode.RenderTargetName); Assert.Single(viewNode.ExposeMembers); Assert.Equal("P::Widget", viewNode.ExposeMembers[0].QualifiedName); Assert.Equal(ExposeRecursionKind.MembershipRecursive, viewNode.ExposeMembers[0].RecursionKind); @@ -76,7 +76,7 @@ public void Synthesize_ResolveExposedScope_NarrowsToTargetSubtreeOnly() Assert.Null(diagnostic); Assert.NotNull(viewNode); - var scope = ExposeScopeResolver.ResolveExposedScope(workspace, viewNode!); + var scope = ExposeScopeResolver.ResolveExposedScope(workspace, viewNode); Assert.NotNull(scope); Assert.True(ExposeScopeResolver.IsInSubjectScope("P::Widget", scope)); @@ -100,7 +100,7 @@ public void Synthesize_GridKind_ResolvableTarget_Succeeds() Assert.Null(diagnostic); Assert.NotNull(viewNode); - Assert.Equal("asGridDiagram", viewNode!.RenderTargetName); + Assert.Equal("asGridDiagram", viewNode.RenderTargetName); } /// A "browser" dynamic view targeting any resolvable non-stdlib definition succeeds. @@ -119,7 +119,7 @@ public void Synthesize_BrowserKind_ResolvableTarget_Succeeds() Assert.Null(diagnostic); Assert.NotNull(viewNode); - Assert.Equal("asTreeDiagram", viewNode!.RenderTargetName); + Assert.Equal("asTreeDiagram", viewNode.RenderTargetName); } /// @@ -146,7 +146,7 @@ public void Synthesize_InterconnectionKind_PartDefWithNestedPart_Succeeds() Assert.Null(diagnostic); Assert.NotNull(viewNode); - Assert.Equal("asInterconnectionDiagram", viewNode!.RenderTargetName); + Assert.Equal("asInterconnectionDiagram", viewNode.RenderTargetName); } /// An "interconnection" dynamic view targeting a non-"part def" fails with a diagnostic. @@ -165,7 +165,7 @@ public void Synthesize_InterconnectionKind_NotPartDef_Fails() Assert.Null(viewNode); Assert.NotNull(diagnostic); - Assert.Contains("part def", diagnostic!, StringComparison.Ordinal); + Assert.Contains("part def", diagnostic, StringComparison.Ordinal); } /// An "interconnection" dynamic view targeting a part def with no nested parts fails. @@ -184,7 +184,7 @@ public void Synthesize_InterconnectionKind_NoNestedParts_Fails() Assert.Null(viewNode); Assert.NotNull(diagnostic); - Assert.Contains("no nested 'part'", diagnostic!, StringComparison.Ordinal); + Assert.Contains("no nested 'part'", diagnostic, StringComparison.Ordinal); } /// A "state" dynamic view targeting a definition with a nested transition succeeds. @@ -209,7 +209,7 @@ public void Synthesize_StateKind_HasTransition_Succeeds() Assert.Null(diagnostic); Assert.NotNull(viewNode); - Assert.Equal("asStateTransitionDiagram", viewNode!.RenderTargetName); + Assert.Equal("asStateTransitionDiagram", viewNode.RenderTargetName); } /// A "state" dynamic view targeting a definition with no transitions fails. @@ -228,7 +228,7 @@ public void Synthesize_StateKind_NoTransitions_Fails() Assert.Null(viewNode); Assert.NotNull(diagnostic); - Assert.Contains("no nested state transitions", diagnostic!, StringComparison.Ordinal); + Assert.Contains("no nested state transitions", diagnostic, StringComparison.Ordinal); } /// @@ -260,7 +260,7 @@ public void Synthesize_StateKind_HasStateFeatureNoTransitions_Succeeds() Assert.Null(diagnostic); Assert.NotNull(viewNode); - Assert.Equal("asStateTransitionDiagram", viewNode!.RenderTargetName); + Assert.Equal("asStateTransitionDiagram", viewNode.RenderTargetName); } /// An "action" dynamic view targeting a definition with an "action" feature succeeds. @@ -285,7 +285,7 @@ public void Synthesize_ActionKind_HasActionFeature_Succeeds() Assert.Null(diagnostic); Assert.NotNull(viewNode); - Assert.Equal("asActionFlowDiagram", viewNode!.RenderTargetName); + Assert.Equal("asActionFlowDiagram", viewNode.RenderTargetName); } /// An "action" dynamic view targeting a definition with a succession succeeds. @@ -328,7 +328,7 @@ public void Synthesize_ActionKind_NoActionsOrSuccessions_Fails() Assert.Null(viewNode); Assert.NotNull(diagnostic); - Assert.Contains("no successions or 'action' features", diagnostic!, StringComparison.Ordinal); + Assert.Contains("no successions or 'action' features", diagnostic, StringComparison.Ordinal); } /// A "sequence" dynamic view targeting a definition with a nested message succeeds. @@ -353,7 +353,7 @@ public void Synthesize_SequenceKind_HasMessage_Succeeds() Assert.Null(diagnostic); Assert.NotNull(viewNode); - Assert.Equal("asSequenceDiagram", viewNode!.RenderTargetName); + Assert.Equal("asSequenceDiagram", viewNode.RenderTargetName); } /// @@ -376,7 +376,7 @@ public void Synthesize_SequenceKind_NoMessages_Fails() Assert.Null(viewNode); Assert.NotNull(diagnostic); - Assert.Contains("no nested messages", diagnostic!, StringComparison.Ordinal); + Assert.Contains("no nested messages", diagnostic, StringComparison.Ordinal); } /// An unrecognized --view-type value fails with a diagnostic listing valid values. @@ -395,7 +395,7 @@ public void Synthesize_UnrecognizedViewType_Fails() Assert.Null(viewNode); Assert.NotNull(diagnostic); - Assert.Contains("unrecognized --view-type", diagnostic!, StringComparison.Ordinal); + Assert.Contains("unrecognized --view-type", diagnostic, StringComparison.Ordinal); } /// An unresolved --view-target fails with a diagnostic. @@ -408,7 +408,7 @@ public void Synthesize_UnresolvedTarget_Fails() Assert.Null(viewNode); Assert.NotNull(diagnostic); - Assert.Contains("was not found", diagnostic!, StringComparison.Ordinal); + Assert.Contains("was not found", diagnostic, StringComparison.Ordinal); } /// A --view-target resolving to a view node (wrong kind) fails with a diagnostic. @@ -427,7 +427,7 @@ public void Synthesize_TargetIsView_Fails() Assert.Null(viewNode); Assert.NotNull(diagnostic); - Assert.Contains("view", diagnostic!, StringComparison.Ordinal); + Assert.Contains("view", diagnostic, StringComparison.Ordinal); } /// A --view-target resolving to a transition (wrong kind) fails with a diagnostic. @@ -446,7 +446,7 @@ public void Synthesize_TargetIsTransition_Fails() Assert.Null(viewNode); Assert.NotNull(diagnostic); - Assert.Contains("transition", diagnostic!, StringComparison.Ordinal); + Assert.Contains("transition", diagnostic, StringComparison.Ordinal); } /// A --view-target resolving to a standard-library element fails with a diagnostic. @@ -466,7 +466,7 @@ public void Synthesize_TargetIsStdlib_Fails() Assert.Null(viewNode); Assert.NotNull(diagnostic); - Assert.Contains("standard-library", diagnostic!, StringComparison.Ordinal); + Assert.Contains("standard-library", diagnostic, StringComparison.Ordinal); } /// The --filter expression text is passed through unchanged to the synthesized node. @@ -485,7 +485,7 @@ public void Synthesize_FilterExpression_PassedThroughUnchanged() Assert.Null(diagnostic); Assert.NotNull(viewNode); - Assert.Equal("@Safety", viewNode!.FilterExpressionText); + Assert.Equal("@Safety", viewNode.FilterExpressionText); } /// A null --filter results in a null FilterExpressionText on the synthesized node. @@ -504,7 +504,7 @@ public void Synthesize_NoFilterExpression_ResultsInNullFilterExpressionText() Assert.Null(diagnostic); Assert.NotNull(viewNode); - Assert.Null(viewNode!.FilterExpressionText); + Assert.Null(viewNode.FilterExpressionText); } /// @@ -527,6 +527,6 @@ public void Synthesize_NameCollision_Fails() Assert.Null(viewNode); Assert.NotNull(diagnostic); - Assert.Contains("already exists", diagnostic!, StringComparison.Ordinal); + Assert.Contains("already exists", diagnostic, StringComparison.Ordinal); } } diff --git a/test/DemaConsulting.SysML2Tools.Tests/Semantic/AstBuilderMetadataTests.cs b/test/DemaConsulting.SysML2Tools.Tests/Semantic/AstBuilderMetadataTests.cs index 2a3fe8b4..f377413e 100644 --- a/test/DemaConsulting.SysML2Tools.Tests/Semantic/AstBuilderMetadataTests.cs +++ b/test/DemaConsulting.SysML2Tools.Tests/Semantic/AstBuilderMetadataTests.cs @@ -44,8 +44,8 @@ part def Engine { var result = await WorkspaceLoader.LoadAsync([tempFile], stdlibTable); Assert.NotNull(result.Workspace); - Assert.True(result.Workspace!.Declarations.TryGetValue("P::Engine", out var engine)); - var metadata = Assert.Single(engine!.Children.OfType()); + Assert.True(result.Workspace.Declarations.TryGetValue("P::Engine", out var engine)); + var metadata = Assert.Single(engine.Children.OfType()); Assert.Equal("Safety", metadata.TypeReference); Assert.Empty(metadata.Attributes); } @@ -86,8 +86,8 @@ part def Engine { var result = await WorkspaceLoader.LoadAsync([tempFile], stdlibTable); Assert.NotNull(result.Workspace); - Assert.True(result.Workspace!.Declarations.TryGetValue("P::Engine", out var engine)); - var metadata = Assert.Single(engine!.Children.OfType()); + Assert.True(result.Workspace.Declarations.TryGetValue("P::Engine", out var engine)); + var metadata = Assert.Single(engine.Children.OfType()); var attribute = Assert.Single(metadata.Attributes); Assert.Equal("isMandatory", attribute.Name); Assert.Equal(MetadataAttributeValueKind.Boolean, attribute.Kind); @@ -129,8 +129,8 @@ part def Engine { var result = await WorkspaceLoader.LoadAsync([tempFile], stdlibTable); Assert.NotNull(result.Workspace); - Assert.True(result.Workspace!.Declarations.TryGetValue("P::Engine", out var engine)); - var metadata = Assert.Single(engine!.Children.OfType()); + Assert.True(result.Workspace.Declarations.TryGetValue("P::Engine", out var engine)); + var metadata = Assert.Single(engine.Children.OfType()); var edge = Assert.Single(metadata.ResolvedEdges); Assert.Equal(SysmlEdgeKind.MetadataType, edge.Kind); Assert.Equal("P::Safety", edge.TargetQualifiedName); @@ -212,7 +212,7 @@ view V { var result = await WorkspaceLoader.LoadAsync([tempFile], stdlibTable); Assert.NotNull(result.Workspace); - Assert.True(result.Workspace!.Declarations.TryGetValue("P::V", out var view)); + Assert.True(result.Workspace.Declarations.TryGetValue("P::V", out var view)); var viewNode = Assert.IsType(view); var member = Assert.Single(viewNode.ExposeMembers); Assert.Equal("P", member.QualifiedName); @@ -264,7 +264,7 @@ view V { var result = await WorkspaceLoader.LoadAsync([tempFile], stdlibTable); Assert.NotNull(result.Workspace); - Assert.True(result.Workspace!.Declarations.TryGetValue("P::V", out var view)); + Assert.True(result.Workspace.Declarations.TryGetValue("P::V", out var view)); var viewNode = Assert.IsType(view); Assert.Equal(2, viewNode.ExposeMembers.Count); @@ -316,7 +316,7 @@ view V { var result = await WorkspaceLoader.LoadAsync([tempFile], stdlibTable); Assert.NotNull(result.Workspace); - Assert.True(result.Workspace!.Declarations.TryGetValue("P::V", out var view)); + Assert.True(result.Workspace.Declarations.TryGetValue("P::V", out var view)); var viewNode = Assert.IsType(view); var member = Assert.Single(viewNode.ExposeMembers); Assert.Equal("Engine", member.QualifiedName); @@ -357,7 +357,7 @@ view V { var result = await WorkspaceLoader.LoadAsync([tempFile], stdlibTable); Assert.NotNull(result.Workspace); - Assert.True(result.Workspace!.Declarations.TryGetValue("P::V", out var view)); + Assert.True(result.Workspace.Declarations.TryGetValue("P::V", out var view)); var viewNode = Assert.IsType(view); var member = Assert.Single(viewNode.ExposeMembers); Assert.Equal("Engine", member.QualifiedName); @@ -396,7 +396,7 @@ view V { var result = await WorkspaceLoader.LoadAsync([tempFile], stdlibTable); Assert.NotNull(result.Workspace); - Assert.True(result.Workspace!.Declarations.TryGetValue("P::V", out var view)); + Assert.True(result.Workspace.Declarations.TryGetValue("P::V", out var view)); var viewNode = Assert.IsType(view); var member = Assert.Single(viewNode.ExposeMembers); Assert.Equal("P", member.QualifiedName); @@ -435,7 +435,7 @@ view V { var result = await WorkspaceLoader.LoadAsync([tempFile], stdlibTable); Assert.NotNull(result.Workspace); - Assert.True(result.Workspace!.Declarations.TryGetValue("P::V", out var view)); + Assert.True(result.Workspace.Declarations.TryGetValue("P::V", out var view)); var viewNode = Assert.IsType(view); var member = Assert.Single(viewNode.ExposeMembers); Assert.Equal("P", member.QualifiedName); diff --git a/test/DemaConsulting.SysML2Tools.Tests/Semantic/WorkspaceLoaderTests.cs b/test/DemaConsulting.SysML2Tools.Tests/Semantic/WorkspaceLoaderTests.cs index 7c7eb6d7..a9695c59 100644 --- a/test/DemaConsulting.SysML2Tools.Tests/Semantic/WorkspaceLoaderTests.cs +++ b/test/DemaConsulting.SysML2Tools.Tests/Semantic/WorkspaceLoaderTests.cs @@ -57,7 +57,7 @@ public async Task WorkspaceLoader_LoadAsync_SinglePackage_RegistersDeclaration() // Assert Assert.NotNull(result.Workspace); - Assert.True(result.Workspace!.Declarations.ContainsKey("Foo"), + Assert.True(result.Workspace.Declarations.ContainsKey("Foo"), "Expected 'Foo' in declarations"); } finally @@ -85,8 +85,8 @@ public async Task WorkspaceLoader_LoadAsync_NestedPackages_RegistersQualifiedNam // Assert Assert.NotNull(result.Workspace); - Assert.True(result.Workspace!.Declarations.ContainsKey("A"), "Expected 'A'"); - Assert.True(result.Workspace!.Declarations.ContainsKey("A::B"), "Expected 'A::B'"); + Assert.True(result.Workspace.Declarations.ContainsKey("A"), "Expected 'A'"); + Assert.True(result.Workspace.Declarations.ContainsKey("A::B"), "Expected 'A::B'"); } finally { @@ -113,7 +113,7 @@ public async Task WorkspaceLoader_LoadAsync_PartDef_RegistersDefinition() // Assert Assert.NotNull(result.Workspace); - Assert.True(result.Workspace!.Declarations.ContainsKey("P::W"), + Assert.True(result.Workspace.Declarations.ContainsKey("P::W"), "Expected 'P::W' in declarations"); } finally @@ -136,7 +136,7 @@ public async Task WorkspaceLoader_LoadAsync_NoFiles_ReturnsNonNullWorkspace() // Assert Assert.NotNull(result.Workspace); // Stdlib has many declarations - Assert.NotEmpty(result.Workspace!.Declarations); + Assert.NotEmpty(result.Workspace.Declarations); } // Level 6: Stdlib declarations are registered @@ -153,7 +153,7 @@ public async Task WorkspaceLoader_LoadAsync_StdlibDeclarations_Registered() // Assert Assert.NotNull(result.Workspace); // Stdlib should register at least some declarations - Assert.True(result.Workspace!.Declarations.Count > 0, + Assert.True(result.Workspace.Declarations.Count > 0, "Expected stdlib declarations to be registered"); // No errors from stdlib loading Assert.False(result.HasErrors); @@ -183,8 +183,8 @@ part def Base {} // Assert Assert.NotNull(result.Workspace); - Assert.True(result.Workspace!.Declarations.ContainsKey("P::Base"), "Expected 'P::Base'"); - Assert.True(result.Workspace!.Declarations.ContainsKey("P::Derived"), "Expected 'P::Derived'"); + Assert.True(result.Workspace.Declarations.ContainsKey("P::Base"), "Expected 'P::Base'"); + Assert.True(result.Workspace.Declarations.ContainsKey("P::Derived"), "Expected 'P::Derived'"); // Supertype should resolve — no unresolved warning for P::Base Assert.DoesNotContain(result.Diagnostics, d => d.Severity == DemaConsulting.SysML2Tools.Parser.DiagnosticSeverity.Warning && @@ -501,7 +501,7 @@ part def Uses { var (stdlibTable, _) = StdlibProvider.GetSymbolTable(); var result = await WorkspaceLoader.LoadAsync([tempFile], stdlibTable); Assert.NotNull(result.Workspace); - var index = result.Workspace!.Index; + var index = result.Workspace.Index; // Assert — "Foo" resolves as a Typing edge to the shallower (one-level-deep) match, // not the deeper-but-shorter-string one. @@ -685,11 +685,11 @@ enum def Gear; // Assert: each definition is registered with its expected keyword Assert.NotNull(result.Workspace); - AssertKeyword(result.Workspace!, "Demo::Vehicle", "part def"); - AssertKeyword(result.Workspace!, "Demo::FuelPort", "port def"); - AssertKeyword(result.Workspace!, "Demo::FuelInterface", "interface def"); - AssertKeyword(result.Workspace!, "Demo::MassReq", "requirement def"); - AssertKeyword(result.Workspace!, "Demo::Gear", "enum def"); + AssertKeyword(result.Workspace, "Demo::Vehicle", "part def"); + AssertKeyword(result.Workspace, "Demo::FuelPort", "port def"); + AssertKeyword(result.Workspace, "Demo::FuelInterface", "interface def"); + AssertKeyword(result.Workspace, "Demo::MassReq", "requirement def"); + AssertKeyword(result.Workspace, "Demo::Gear", "enum def"); } finally { @@ -716,7 +716,7 @@ public async Task WorkspaceLoader_LoadAsync_PopulatesStdlibNamesFromSeed() // Assert: stdlib names are recorded and the user declaration is not among them Assert.NotNull(result.Workspace); - Assert.NotEmpty(result.Workspace!.StdlibNames); + Assert.NotEmpty(result.Workspace.StdlibNames); Assert.DoesNotContain("UserPkg::UserPart", result.Workspace.StdlibNames); } finally @@ -756,7 +756,7 @@ part def Vehicle { // Assert: the Vehicle definition owns three feature children with the expected typing Assert.NotNull(result.Workspace); var vehicle = Assert.IsType( - result.Workspace!.Declarations["Demo::Vehicle"]); + result.Workspace.Declarations["Demo::Vehicle"]); var features = vehicle.Children .OfType() .ToList(); @@ -801,7 +801,7 @@ part def Drivetrain { // Assert: the Drivetrain owns a connection node referencing both parts Assert.NotNull(result.Workspace); var drivetrain = Assert.IsType( - result.Workspace!.Declarations["Demo::Drivetrain"]); + result.Workspace.Declarations["Demo::Drivetrain"]); var connection = drivetrain.Children .OfType() .Single(); @@ -843,7 +843,7 @@ state def Light { // Assert: the state def owns two state features and one transition Assert.NotNull(result.Workspace); var light = Assert.IsType( - result.Workspace!.Declarations["SM::Light"]); + result.Workspace.Declarations["SM::Light"]); var states = light.Children .OfType() .Where(f => f.FeatureKeyword == "state") @@ -891,7 +891,7 @@ action def Flow { // Assert: the action def owns two action features and one succession Assert.NotNull(result.Workspace); var flow = Assert.IsType( - result.Workspace!.Declarations["AF::Flow"]); + result.Workspace.Declarations["AF::Flow"]); var actions = flow.Children .OfType() .Count(f => f.FeatureKeyword == "action"); @@ -937,7 +937,7 @@ part def Protocol { // Assert: the protocol owns a message connection with the expected endpoints Assert.NotNull(result.Workspace); var protocol = Assert.IsType( - result.Workspace!.Declarations["Seq::Protocol"]); + result.Workspace.Declarations["Seq::Protocol"]); var message = protocol.Children .OfType() .Single(c => c.ConnectionKeyword == "message"); @@ -975,7 +975,7 @@ part def Child specializes Ancestor {} // Assert Assert.NotNull(result.Workspace); - var outgoing = result.Workspace!.Index.GetOutgoingEdges("A::Child"); + var outgoing = result.Workspace.Index.GetOutgoingEdges("A::Child"); Assert.Contains(outgoing, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Supertype && e.TargetQualifiedName == "A::Ancestor"); @@ -1015,7 +1015,7 @@ part def Car { // Assert Assert.NotNull(result.Workspace); - var outgoing = result.Workspace!.Index.GetOutgoingEdges("Car::engine"); + var outgoing = result.Workspace.Index.GetOutgoingEdges("Car::engine"); Assert.Contains(outgoing, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Typing && e.TargetQualifiedName == "Engine"); @@ -1060,7 +1060,7 @@ part def X { Assert.Contains(result.Diagnostics, d => d.Severity == DemaConsulting.SysML2Tools.Parser.DiagnosticSeverity.Warning && d.Message.Contains("NonExistentType")); - Assert.DoesNotContain(result.Workspace!.Index.AllEdges, + Assert.DoesNotContain(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Typing && e.TargetQualifiedName == "NonExistentType"); } @@ -1097,7 +1097,7 @@ part def Vehicle { // Assert Assert.NotNull(result.Workspace); var smallVehicle = Assert.IsType( - result.Workspace!.Declarations["SmallVehicle"]); + result.Workspace.Declarations["SmallVehicle"]); var smallEng = smallVehicle.Children .OfType() .First(f => f.Name == "smallEng"); @@ -1137,7 +1137,7 @@ part def Vehicle { // Assert Assert.NotNull(result.Workspace); var smallVehicle = Assert.IsType( - result.Workspace!.Declarations["SmallVehicle"]); + result.Workspace.Declarations["SmallVehicle"]); var smallEng = smallVehicle.Children .OfType() .First(f => f.Name == "smallEng"); @@ -1177,7 +1177,7 @@ part def Vehicle { // Assert Assert.NotNull(result.Workspace); var car = Assert.IsType( - result.Workspace!.Declarations["Car"]); + result.Workspace.Declarations["Car"]); var carMass = car.Children .OfType() .First(f => f.Name == "carMass"); @@ -1215,7 +1215,7 @@ part def Vehicle { // Assert Assert.NotNull(result.Workspace); var vehicle = Assert.IsType( - result.Workspace!.Declarations["Vehicle"]); + result.Workspace.Declarations["Vehicle"]); var mass = vehicle.Children .OfType() .First(f => f.Name == "mass"); @@ -1260,7 +1260,7 @@ port redefines tank.fuelTankPort { // Assert Assert.NotNull(result.Workspace); var vehicle = Assert.IsType( - result.Workspace!.Declarations["Vehicle"]); + result.Workspace.Declarations["Vehicle"]); var implicitlyNamedPort = vehicle.Children .OfType() .First(f => f.RedefinedFeatureName == "tank.fuelTankPort"); @@ -1298,7 +1298,7 @@ part def SmallVehicle { // Assert Assert.NotNull(result.Workspace); - var outgoing = result.Workspace!.Index.GetOutgoingEdges("SmallVehicle::smallEng"); + var outgoing = result.Workspace.Index.GetOutgoingEdges("SmallVehicle::smallEng"); Assert.Contains(outgoing, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Redefinition && e.TargetQualifiedName == "eng"); @@ -1343,7 +1343,7 @@ part def X { Assert.Contains(result.Diagnostics, d => d.Severity == DemaConsulting.SysML2Tools.Parser.DiagnosticSeverity.Warning && d.Message.Contains("NonExistentFeature")); - Assert.DoesNotContain(result.Workspace!.Index.AllEdges, + Assert.DoesNotContain(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Redefinition && e.TargetQualifiedName == "NonExistentFeature"); } @@ -1388,7 +1388,7 @@ part def Vehicle { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Redefinition && e.SourceQualifiedName == "SmallVehicle::smallEng" && e.TargetQualifiedName == "Vehicle::eng"); @@ -1516,7 +1516,7 @@ part def GrandParent { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Redefinition && e.SourceQualifiedName == "Mid::value" && e.TargetQualifiedName == "GrandParent::feat"); @@ -1564,7 +1564,7 @@ part def GrandParent { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Redefinition && e.SourceQualifiedName == "Mid::value" && e.TargetQualifiedName == "GrandParent::feat"); @@ -1608,7 +1608,7 @@ part def Thing { // Assert Assert.NotNull(result.Workspace); - var thingNode = result.Workspace!.Declarations["Thing"]; + var thingNode = result.Workspace.Declarations["Thing"]; var xNode = Assert.Single(thingNode.Children, c => c.Name == "x"); Assert.Contains("y", xNode.SupertypeNames); Assert.Contains(result.Workspace.Index.AllEdges, @@ -1648,7 +1648,7 @@ package Consumer { // Assert Assert.NotNull(result.Workspace); - var incoming = result.Workspace!.Index.GetIncomingEdges("Other"); + var incoming = result.Workspace.Index.GetIncomingEdges("Other"); Assert.Contains(incoming, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Import); } finally @@ -1681,7 +1681,7 @@ package Consumer { // Assert Assert.NotNull(result.Workspace); - var incoming = result.Workspace!.Index.GetIncomingEdges("Other::Thing"); + var incoming = result.Workspace.Index.GetIncomingEdges("Other::Thing"); Assert.Contains(incoming, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Import); } finally @@ -1715,7 +1715,7 @@ part def Baz specializes Foo {} // Assert — the edge's target must be the fully-qualified "A::Foo", not raw "Foo" Assert.NotNull(result.Workspace); - var outgoing = result.Workspace!.Index.GetOutgoingEdges("A::Baz"); + var outgoing = result.Workspace.Index.GetOutgoingEdges("A::Baz"); Assert.Contains(outgoing, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Supertype && e.TargetQualifiedName == "A::Foo"); @@ -1791,7 +1791,7 @@ part def Gadget specializes Ancestor { // Assert Assert.NotNull(result.Workspace); - var index = result.Workspace!.Index; + var index = result.Workspace.Index; // Supertype edge, both directions Assert.Contains(index.GetOutgoingEdges("App::Gadget"), @@ -1848,7 +1848,7 @@ part def Q {} // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Satisfy && e.SourceQualifiedName == "P::subj" && e.TargetQualifiedName == "P::req"); @@ -1887,7 +1887,7 @@ package P { Assert.Contains(result.Diagnostics, d => d.Severity == DemaConsulting.SysML2Tools.Parser.DiagnosticSeverity.Warning && d.Message.Contains("nonExistentSubject")); - Assert.DoesNotContain(result.Workspace!.Index.AllEdges, + Assert.DoesNotContain(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Satisfy); } finally @@ -1924,7 +1924,7 @@ part def Q {} Assert.Contains(result.Diagnostics, d => d.Severity == DemaConsulting.SysML2Tools.Parser.DiagnosticSeverity.Warning && d.Message.Contains("nonExistentReq")); - Assert.DoesNotContain(result.Workspace!.Index.AllEdges, + Assert.DoesNotContain(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Satisfy); } finally @@ -1966,7 +1966,7 @@ part def Q { Assert.Contains(result.Diagnostics, d => d.Severity == DemaConsulting.SysML2Tools.Parser.DiagnosticSeverity.Warning && d.Message.Contains("container.sub")); - Assert.DoesNotContain(result.Workspace!.Index.AllEdges, + Assert.DoesNotContain(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Satisfy); } finally @@ -2004,7 +2004,7 @@ requirement outer { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Verify && e.SourceQualifiedName == "P::outer" && e.TargetQualifiedName == "P::req"); @@ -2042,7 +2042,7 @@ requirement outer { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Verify && e.SourceQualifiedName == "P::outer" && e.TargetQualifiedName == "P::R"); @@ -2084,7 +2084,7 @@ objective obj { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Verify && e.SourceQualifiedName == "P::C" && e.TargetQualifiedName == "P::R"); @@ -2125,7 +2125,7 @@ requirement outer { Assert.Contains(result.Diagnostics, d => d.Severity == DemaConsulting.SysML2Tools.Parser.DiagnosticSeverity.Warning && d.Message.Contains("nonExistentReq")); - Assert.DoesNotContain(result.Workspace!.Index.AllEdges, + Assert.DoesNotContain(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Verify); } finally @@ -2161,7 +2161,7 @@ part def Q {} // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Allocate && e.SourceQualifiedName == "P::a" && e.TargetQualifiedName == "P::b"); @@ -2200,7 +2200,7 @@ part def Q {} Assert.Contains(result.Diagnostics, d => d.Severity == DemaConsulting.SysML2Tools.Parser.DiagnosticSeverity.Warning && d.Message.Contains("nonExistentEnd")); - Assert.DoesNotContain(result.Workspace!.Index.AllEdges, + Assert.DoesNotContain(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Allocate); } finally @@ -2235,7 +2235,7 @@ part def Q {} // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Dependency && e.SourceQualifiedName == "P::a" && e.TargetQualifiedName == "P::b"); @@ -2274,7 +2274,7 @@ part def Q {} // Assert Assert.NotNull(result.Workspace); - var edges = result.Workspace!.Index.AllEdges + var edges = result.Workspace.Index.AllEdges .Where(e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Dependency) .Select(e => (e.SourceQualifiedName, e.TargetQualifiedName)) .ToList(); @@ -2318,7 +2318,7 @@ part def Q {} Assert.Contains(result.Diagnostics, d => d.Severity == DemaConsulting.SysML2Tools.Parser.DiagnosticSeverity.Warning && d.Message.Contains("nonExistentEnd")); - Assert.DoesNotContain(result.Workspace!.Index.AllEdges, + Assert.DoesNotContain(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Dependency); } finally @@ -2361,7 +2361,7 @@ part def Q { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Binding && e.SourceQualifiedName == "P::Q::a::x" && e.TargetQualifiedName == "P::Q::b::y"); @@ -2418,7 +2418,7 @@ port redefines fuelTankPort { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Binding && e.SourceQualifiedName == "P::Vehicle::tank::fuelTankPort::fuelSupply" && e.TargetQualifiedName == "P::Vehicle::pump::pumpOut"); @@ -2462,7 +2462,7 @@ part def Q { Assert.Contains(result.Diagnostics, d => d.Severity == DemaConsulting.SysML2Tools.Parser.DiagnosticSeverity.Warning && d.Message.Contains("nonExistentEnd")); - Assert.DoesNotContain(result.Workspace!.Index.AllEdges, + Assert.DoesNotContain(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Binding); } finally @@ -2509,7 +2509,7 @@ objective obj { // Assert Assert.NotNull(result.Workspace); - var index = result.Workspace!.Index; + var index = result.Workspace.Index; // Satisfy edge, both directions Assert.Contains(index.GetOutgoingEdges("P::subj"), @@ -2568,7 +2568,7 @@ part def Q {} // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Connect && e.SourceQualifiedName == "P::a" && e.TargetQualifiedName == "P::b"); @@ -2613,7 +2613,7 @@ part transmission { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Connect && e.SourceQualifiedName == "P::vehicle::engine::fuelPort" && e.TargetQualifiedName == "P::vehicle::transmission::input"); @@ -2658,7 +2658,7 @@ part vehicle { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Connect && e.SourceQualifiedName == "P::vehicle::engine::fuelCmdPort" && e.TargetQualifiedName == "P::vehicle::transmission::input"); @@ -2703,7 +2703,7 @@ part rearAxle { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Connect && e.SourceQualifiedName == "P::rearAxle::leftHalfAxle::axleToWheelPort" && e.TargetQualifiedName == "P::leftWheel::wheelToAxlePort"); @@ -2747,7 +2747,7 @@ part def Wheel { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Connect && e.SourceQualifiedName == "P::rearAxleAssembly::shaftPort" && e.TargetQualifiedName == "P::leftWheel::wheelToAxlePort"); @@ -2802,7 +2802,7 @@ part def Wheel { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Connect && e.SourceQualifiedName == "P::rearAxle::leftHalfAxle::axleToWheelPort" && e.TargetQualifiedName == "P::leftWheel::wheelToAxlePort"); @@ -2852,7 +2852,7 @@ part def Drone { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Connect && e.SourceQualifiedName == "P::Drone::controller::power" && e.TargetQualifiedName == "P::Drone::battery::output"); @@ -2896,7 +2896,7 @@ part def Transmission {} Assert.Contains(result.Diagnostics, d => d.Severity == DemaConsulting.SysML2Tools.Parser.DiagnosticSeverity.Warning && d.Message.Contains("transmission.nonExistentPort")); - Assert.DoesNotContain(result.Workspace!.Index.AllEdges, + Assert.DoesNotContain(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Connect); } finally @@ -2932,7 +2932,7 @@ part def Q {} // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Connect && e.SourceQualifiedName == "P::a" && e.TargetQualifiedName == "P::b"); @@ -2970,7 +2970,7 @@ state def Behavior { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Transition && e.SourceQualifiedName == "P::Behavior::start" && e.TargetQualifiedName == "P::Behavior::off"); @@ -3015,7 +3015,7 @@ accept Signal via requestPort // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Transition && e.SourceQualifiedName == "P::Behavior::off" && e.TargetQualifiedName == "P::Behavior::off"); @@ -3059,7 +3059,7 @@ accept Signal via requestPort // Assert Assert.NotNull(result.Workspace); - Assert.DoesNotContain(result.Workspace!.Index.AllEdges, + Assert.DoesNotContain(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Transition); } finally @@ -3100,11 +3100,11 @@ state def Behavior { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Transition && e.SourceQualifiedName == "P::Behavior::a" && e.TargetQualifiedName == "P::Behavior::b"); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Transition && e.SourceQualifiedName == "P::Behavior::a" && e.TargetQualifiedName == "P::Behavior::c"); @@ -3144,7 +3144,7 @@ state def Behavior { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Transition && e.SourceQualifiedName == "P::Behavior::initial" && e.TargetQualifiedName == "P::Behavior::off"); @@ -3186,7 +3186,7 @@ state def Behavior { Assert.NotNull(result.Workspace); Assert.DoesNotContain(result.Diagnostics, d => d.Message.Contains("Unresolved reference: 'initial'", StringComparison.Ordinal)); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Transition && e.SourceQualifiedName == "P::Behavior::initial" && e.TargetQualifiedName == "P::Behavior::off"); @@ -3262,7 +3262,7 @@ package P { // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Typing && e.SourceQualifiedName == "P::usage" && e.TargetQualifiedName == "P::X"); @@ -3306,7 +3306,7 @@ package P { Assert.NotNull(result.Workspace); Assert.DoesNotContain(result.Diagnostics, d => d.Message.Contains("Unresolved reference: 'start'", StringComparison.Ordinal)); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Transition && e.SourceQualifiedName == "Actions::Action::start" && e.TargetQualifiedName == "P::usage::y"); @@ -3351,7 +3351,7 @@ part def Q {} Assert.Same(loadTask, completed); var result = await loadTask; Assert.NotNull(result.Workspace); - Assert.DoesNotContain(result.Workspace!.Index.AllEdges, + Assert.DoesNotContain(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Connect); } finally @@ -3387,7 +3387,7 @@ public async Task WorkspaceLoader_LoadAsync_ConnectionsExampleFixture_RecordsCon // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Connect); } @@ -3420,7 +3420,7 @@ public async Task WorkspaceLoader_LoadAsync_2aPartsInterconnectionFixture_Record // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Connect); } @@ -3453,7 +3453,7 @@ public async Task WorkspaceLoader_LoadAsync_2cPartsInterconnectionFixture_Record // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Connect); } @@ -3485,7 +3485,7 @@ public async Task WorkspaceLoader_LoadAsync_StateDefinitionExampleFixture_Record // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Transition); } @@ -3519,7 +3519,7 @@ public async Task WorkspaceLoader_LoadAsync_RequirementSatisfactionFixture_Recor // Assert — smoke test: at least one Satisfy edge is present (exact resolved names are not // pinned, since the fixture spans multiple files and packages) Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Satisfy); } @@ -3551,7 +3551,7 @@ public async Task WorkspaceLoader_LoadAsync_8RequirementsFixture_RecordsSatisfyE // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Satisfy); } @@ -3583,7 +3583,7 @@ public async Task WorkspaceLoader_LoadAsync_12bAllocationFixture_RecordsAllocate // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Allocate); } @@ -3617,7 +3617,7 @@ public async Task WorkspaceLoader_LoadAsync_9VerificationSimplifiedFixture_Recor // Assert Assert.NotNull(result.Workspace); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Verify); } @@ -3645,7 +3645,7 @@ package P { // Assert Assert.NotNull(result.Workspace); - var package = result.Workspace!.Declarations["P"]; + var package = result.Workspace.Declarations["P"]; var annotation = Assert.Single(package.Annotations); Assert.Equal(DemaConsulting.SysML2Tools.Semantic.Model.SysmlAnnotationKind.Comment, annotation.Kind); Assert.Equal(" a note about P ", annotation.Text); @@ -3680,7 +3680,7 @@ package P { // Assert Assert.NotNull(result.Workspace); - var package = result.Workspace!.Declarations["P"]; + var package = result.Workspace.Declarations["P"]; var annotation = Assert.Single(package.Annotations); Assert.Equal(DemaConsulting.SysML2Tools.Semantic.Model.SysmlAnnotationKind.Documentation, annotation.Kind); Assert.Equal(" documentation about P ", annotation.Text); @@ -3715,7 +3715,7 @@ package P { // Assert Assert.NotNull(result.Workspace); - var package = result.Workspace!.Declarations["P"]; + var package = result.Workspace.Declarations["P"]; Assert.Equal(2, package.Annotations.Count); Assert.Equal(DemaConsulting.SysML2Tools.Semantic.Model.SysmlAnnotationKind.Comment, package.Annotations[0].Kind); Assert.Equal(" first: a comment ", package.Annotations[0].Text); @@ -3747,7 +3747,7 @@ public async Task WorkspaceLoader_LoadAsync_NoAnnotations_AnnotationsIsEmptyNotN // Assert Assert.NotNull(result.Workspace); - var package = result.Workspace!.Declarations["P"]; + var package = result.Workspace.Declarations["P"]; Assert.NotNull(package.Annotations); Assert.Empty(package.Annotations); } @@ -3781,7 +3781,7 @@ await File.WriteAllTextAsync(tempFile, // Assert Assert.NotNull(result.Workspace); - var package = result.Workspace!.Declarations["P"]; + var package = result.Workspace.Declarations["P"]; var annotation = Assert.Single(package.Annotations); Assert.Equal(" line one\n * line two\n ", annotation.Text); } @@ -3819,7 +3819,7 @@ public async Task WorkspaceLoader_LoadAsync_DocumentationExampleFixture_Captures // Assert — package-level doc Assert.NotNull(result.Workspace); var package = Assert.IsType( - result.Workspace!.Declarations["'Documentation Example'"]); + result.Workspace.Declarations["'Documentation Example'"]); var packageDoc = Assert.Single(package.Annotations); Assert.Equal(DemaConsulting.SysML2Tools.Semantic.Model.SysmlAnnotationKind.Documentation, packageDoc.Kind); Assert.Contains("This is documentation of the owning", packageDoc.Text); @@ -3827,7 +3827,7 @@ public async Task WorkspaceLoader_LoadAsync_DocumentationExampleFixture_Captures // Assert — part-def-level named doc var automobile = Assert.IsType( - result.Workspace!.Declarations["'Documentation Example'::Automobile"]); + result.Workspace.Declarations["'Documentation Example'::Automobile"]); var automobileDoc = Assert.Single(automobile.Annotations); Assert.Equal(DemaConsulting.SysML2Tools.Semantic.Model.SysmlAnnotationKind.Documentation, automobileDoc.Kind); Assert.Equal(" This documentation of Automobile. ", automobileDoc.Text); @@ -3863,10 +3863,10 @@ view def V { // Assert Assert.NotNull(result.Workspace); var view = Assert.IsType( - result.Workspace!.Declarations["P::V"]); + result.Workspace.Declarations["P::V"]); Assert.Equal("asTreeDiagram", view.RenderTargetName); Assert.Empty(result.Diagnostics); - Assert.DoesNotContain(result.Workspace!.Index.AllEdges, + Assert.DoesNotContain(result.Workspace.Index.AllEdges, e => e.SourceQualifiedName == "P::V"); } finally @@ -3903,10 +3903,10 @@ view def V { // Assert Assert.NotNull(result.Workspace); var view = Assert.IsType( - result.Workspace!.Declarations["P::V"]); + result.Workspace.Declarations["P::V"]); Assert.Equal("@SysML::PartUsage", view.FilterExpressionText); Assert.Empty(result.Diagnostics); - Assert.DoesNotContain(result.Workspace!.Index.AllEdges, + Assert.DoesNotContain(result.Workspace.Index.AllEdges, e => e.SourceQualifiedName == "P::V"); } finally @@ -3945,9 +3945,9 @@ view V { // Assert Assert.NotNull(result.Workspace); var view = Assert.IsType( - result.Workspace!.Declarations["P::V"]); + result.Workspace.Declarations["P::V"]); Assert.Contains("Exposed", view.GetExposedNames()); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Expose && e.SourceQualifiedName == "P::V" && e.TargetQualifiedName == "P::Exposed"); @@ -3993,9 +3993,9 @@ view V { // Assert Assert.NotNull(result.Workspace); var view = Assert.IsType( - result.Workspace!.Declarations["P::V"]); + result.Workspace.Declarations["P::V"]); Assert.Contains("Exposed", view.GetExposedNames()); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Expose && e.SourceQualifiedName == "P::V" && e.TargetQualifiedName == "P::Exposed"); @@ -4035,9 +4035,9 @@ view V { // Assert Assert.NotNull(result.Workspace); var view = Assert.IsType( - result.Workspace!.Declarations["P::V"]); + result.Workspace.Declarations["P::V"]); Assert.Contains("Exposed", view.GetExposedNames()); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Expose && e.SourceQualifiedName == "P::V" && e.TargetQualifiedName == "P::Exposed"); @@ -4084,9 +4084,9 @@ public async Task WorkspaceLoader_LoadAsync_OmgSafetyFeatureViewsFixture_Resolve // Assert Assert.NotNull(result.Workspace); var view = Assert.IsType( - result.Workspace!.Declarations["'11b-Safety and Security Feaure Views'::Views::vehicleMandatorySafetyFeatureViewStandalone"]); + result.Workspace.Declarations["'11b-Safety and Security Feaure Views'::Views::vehicleMandatorySafetyFeatureViewStandalone"]); Assert.NotEmpty(view.GetExposedNames()); - Assert.Contains(result.Workspace!.Index.AllEdges, + Assert.Contains(result.Workspace.Index.AllEdges, e => e.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlEdgeKind.Expose && e.SourceQualifiedName == "'11b-Safety and Security Feaure Views'::Views::vehicleMandatorySafetyFeatureViewStandalone" && e.TargetQualifiedName == "'11b-Safety and Security Feaure Views'::PartsTree::vehicle"); @@ -4121,7 +4121,7 @@ view def V {} // Assert Assert.NotNull(result.Workspace); var view = Assert.IsType( - result.Workspace!.Declarations["P::V"]); + result.Workspace.Declarations["P::V"]); Assert.Null(view.RenderTargetName); Assert.Null(view.FilterExpressionText); Assert.Empty(view.GetExposedNames()); @@ -4160,7 +4160,7 @@ action def Flow { Assert.NotNull(result.Workspace); var flow = Assert.IsType( - result.Workspace!.Declarations["AF::Flow"]); + result.Workspace.Declarations["AF::Flow"]); var actions = flow.Children .OfType() .Count(f => f.FeatureKeyword == "action"); @@ -4210,7 +4210,7 @@ action def Flow { Assert.NotNull(result.Workspace); var flow = Assert.IsType( - result.Workspace!.Declarations["AF::Flow"]); + result.Workspace.Declarations["AF::Flow"]); var successions = flow.Children .OfType() .Where(t => t.Source == "f") @@ -4255,7 +4255,7 @@ action def Flow { Assert.NotNull(result.Workspace); var flow = Assert.IsType( - result.Workspace!.Declarations["AF::Flow"]); + result.Workspace.Declarations["AF::Flow"]); Assert.Empty(flow.Children.OfType()); } finally @@ -4290,7 +4290,7 @@ action def Flow { Assert.NotNull(result.Workspace); var flow = Assert.IsType( - result.Workspace!.Declarations["AF::Flow"]); + result.Workspace.Declarations["AF::Flow"]); var succession = flow.Children .OfType() .Single(); @@ -4342,7 +4342,7 @@ action def Flow { Assert.NotNull(result.Workspace); var flow = Assert.IsType( - result.Workspace!.Declarations["AF::Flow"]); + result.Workspace.Declarations["AF::Flow"]); var features = flow.Children.OfType().ToList(); foreach (var keyword in new[] { "fork", "join", "decide", "merge" }) @@ -4391,7 +4391,7 @@ action def Flow { Assert.NotNull(result.Workspace); var flow = Assert.IsType( - result.Workspace!.Declarations["AF::Flow"]); + result.Workspace.Declarations["AF::Flow"]); var features = flow.Children.OfType().ToList(); var fork = Assert.Single(features, f => f.FeatureKeyword == "fork" && f.Name == "f"); @@ -4403,9 +4403,9 @@ action def Flow { // The named control nodes must actually be registered in the symbol table (this is // the crux of the fix: previously QualifiedName was always null, so RegisterAll never // registered named fork/join/merge/decide/accept/send nodes). - Assert.True(result.Workspace!.Declarations.TryGetValue("AF::Flow::f", out var forkSymbol)); + Assert.True(result.Workspace.Declarations.TryGetValue("AF::Flow::f", out var forkSymbol)); Assert.Same(fork, forkSymbol); - Assert.True(result.Workspace!.Declarations.TryGetValue("AF::Flow::j", out var joinSymbol)); + Assert.True(result.Workspace.Declarations.TryGetValue("AF::Flow::j", out var joinSymbol)); Assert.Same(join, joinSymbol); } finally @@ -4443,7 +4443,7 @@ action def Flow { Assert.NotNull(result.Workspace); var flow = Assert.IsType( - result.Workspace!.Declarations["AF::Flow"]); + result.Workspace.Declarations["AF::Flow"]); var successions = flow.Children .OfType() .Where(t => t.Source == "d") @@ -4488,7 +4488,7 @@ enum red; Assert.NotNull(result.Workspace); var color = Assert.IsType( - result.Workspace!.Declarations["E::TrafficLightColor"]); + result.Workspace.Declarations["E::TrafficLightColor"]); var values = color.Children .OfType() .Where(f => f.FeatureKeyword == "enum value") @@ -4529,7 +4529,7 @@ enum def GradePoints :> Real { Assert.NotNull(result.Workspace); var grades = Assert.IsType( - result.Workspace!.Declarations["E::GradePoints"]); + result.Workspace.Declarations["E::GradePoints"]); var values = grades.Children .OfType() .Where(f => f.FeatureKeyword == "enum value") @@ -4582,7 +4582,7 @@ assume constraint { vehicle.dryMass > 0 } Assert.NotNull(result.Workspace); var massLimitation = Assert.IsType( - result.Workspace!.Declarations["R::MassLimitationRequirement"]); + result.Workspace.Declarations["R::MassLimitationRequirement"]); Assert.Contains(massLimitation.Annotations, a => a.Kind == DemaConsulting.SysML2Tools.Semantic.Model.SysmlAnnotationKind.Documentation); var requireConstraint = Assert.Single(massLimitation.Children @@ -4592,7 +4592,7 @@ assume constraint { vehicle.dryMass > 0 } Assert.Contains("massReqd", requireConstraint.ExpressionText); var vehicleRequirement = Assert.IsType( - result.Workspace!.Declarations["R::VehicleMassLimitationRequirement"]); + result.Workspace.Declarations["R::VehicleMassLimitationRequirement"]); var subject = Assert.Single(vehicleRequirement.Children .OfType(), f => f.FeatureKeyword == "subject"); @@ -4646,7 +4646,7 @@ assume constraint { Assert.NotNull(result.Workspace); var usage = Assert.IsType( - result.Workspace!.Declarations["R::fullVehicleMassLimit"]); + result.Workspace.Declarations["R::fullVehicleMassLimit"]); var subject = Assert.Single(usage.Children .OfType(), @@ -4698,7 +4698,7 @@ concern def SafetyConcern { Assert.NotNull(result.Workspace); var concernDef = Assert.IsType( - result.Workspace!.Declarations["Cn::SafetyConcern"]); + result.Workspace.Declarations["Cn::SafetyConcern"]); Assert.Equal("concern def", concernDef.DefinitionKeyword); var defSubject = Assert.Single(concernDef.Children .OfType(), @@ -4706,7 +4706,7 @@ concern def SafetyConcern { Assert.Equal("vehicle", defSubject.Name); var concernUsage = Assert.IsType( - result.Workspace!.Declarations["Cn::vehicleSafety"]); + result.Workspace.Declarations["Cn::vehicleSafety"]); Assert.Equal("concern", concernUsage.FeatureKeyword); var usageSubject = Assert.Single(concernUsage.Children .OfType(), @@ -4743,7 +4743,7 @@ constraint massCheck { Assert.NotNull(result.Workspace); var constraint = Assert.IsType( - result.Workspace!.Declarations["C::massCheck"]); + result.Workspace.Declarations["C::massCheck"]); Assert.Equal("constraint", constraint.FeatureKeyword); Assert.Contains("1==1", constraint.ExpressionText); } @@ -4778,7 +4778,7 @@ constraint def MassCheck { Assert.NotNull(result.Workspace); var def = Assert.IsType( - result.Workspace!.Declarations["C::MassCheck"]); + result.Workspace.Declarations["C::MassCheck"]); var expressionChild = Assert.Single(def.Children .OfType()); Assert.Equal("constraint", expressionChild.FeatureKeyword); @@ -4818,7 +4818,7 @@ requirement def DriveRequirement { Assert.NotNull(result.Workspace); var req = Assert.IsType( - result.Workspace!.Declarations["R::DriveRequirement"]); + result.Workspace.Declarations["R::DriveRequirement"]); var features = req.Children.OfType().ToList(); var actor = Assert.Single(features, f => f.FeatureKeyword == "actor"); @@ -4871,7 +4871,7 @@ requirement def CheckMass { Assert.NotNull(result.Workspace); var checkMass = Assert.IsType( - result.Workspace!.Declarations["R::CheckMass"]); + result.Workspace.Declarations["R::CheckMass"]); // The verify member's own nested subject must not appear anywhere in CheckMass's // Children — neither as a direct child nor spuriously flattened into one. The @@ -4922,7 +4922,7 @@ private static void AssertFeature( { var feature = features.FirstOrDefault(f => f.Name == name); Assert.NotNull(feature); - Assert.Equal(keyword, feature!.FeatureKeyword); + Assert.Equal(keyword, feature.FeatureKeyword); Assert.Equal(typing, feature.FeatureTyping); } diff --git a/test/DemaConsulting.SysML2Tools.Tool.Tests/Export/ExportRenderingTests.cs b/test/DemaConsulting.SysML2Tools.Tool.Tests/Export/ExportRenderingTests.cs index fca3592b..6644fdbd 100644 --- a/test/DemaConsulting.SysML2Tools.Tool.Tests/Export/ExportRenderingTests.cs +++ b/test/DemaConsulting.SysML2Tools.Tool.Tests/Export/ExportRenderingTests.cs @@ -62,7 +62,7 @@ public void ExportResultSerializerContext_DefinitionNode_RoundTripsTypeDiscrimin var deserialized = JsonSerializer.Deserialize(json, ExportResultSerializerContext.Default.ExportResult); Assert.NotNull(deserialized); - var roundTripped = Assert.IsType(deserialized!.Declarations["Model::Wheel"]); + var roundTripped = Assert.IsType(deserialized.Declarations["Model::Wheel"]); Assert.Equal("part def", roundTripped.DefinitionKeyword); } @@ -116,7 +116,7 @@ public void ExportResultSerializerContext_EdgeKind_RoundTripsExactly(SysmlEdgeKi var deserialized = JsonSerializer.Deserialize(json, ExportResultSerializerContext.Default.ExportResult); Assert.NotNull(deserialized); - var roundTripped = Assert.Single(deserialized!.Edges); + var roundTripped = Assert.Single(deserialized.Edges); Assert.Equal(kind, roundTripped.Kind); Assert.Equal("Model::A", roundTripped.SourceQualifiedName); Assert.Equal("Model::B", roundTripped.TargetQualifiedName); @@ -212,7 +212,7 @@ public void ExportIntegration_RealFixture_ProducesValidJsonAndJsonl() var fixtureRoot = FindSysMlModelsRoot(); Assert.NotNull(fixtureRoot); - var fixtureFile = Path.Combine(fixtureRoot!, "OMG", "examples", "VehicleExample", "VehicleDefinitions.sysml"); + var fixtureFile = Path.Combine(fixtureRoot, "OMG", "examples", "VehicleExample", "VehicleDefinitions.sysml"); Assert.True(File.Exists(fixtureFile), $"Could not find fixture file at {fixtureFile}"); // --- JSON, default (stdlib excluded) --- @@ -287,7 +287,7 @@ public void ExportIntegration_RealFixture_TargetAndFilter_ProducesScopedJson() var fixtureRoot = FindSysMlModelsRoot(); Assert.NotNull(fixtureRoot); - var fixtureFile = Path.Combine(fixtureRoot!, "OMG", "examples", "VehicleExample", "VehicleDefinitions.sysml"); + var fixtureFile = Path.Combine(fixtureRoot, "OMG", "examples", "VehicleExample", "VehicleDefinitions.sysml"); Assert.True(File.Exists(fixtureFile), $"Could not find fixture file at {fixtureFile}"); // --- Unscoped baseline, for a size comparison below --- @@ -335,7 +335,7 @@ public void ExportIntegration_RealFixture_TargetAndFilter_ProducesScopedJson() var target = edge.GetProperty("TargetQualifiedName").GetString(); Assert.NotNull(target); Assert.True( - target == "VehicleDefinitions::Vehicle" || target!.StartsWith("VehicleDefinitions::Vehicle::", StringComparison.Ordinal), + target == "VehicleDefinitions::Vehicle" || target.StartsWith("VehicleDefinitions::Vehicle::", StringComparison.Ordinal), $"Edge target '{target}' is outside the --target subtree."); var source = edge.GetProperty("SourceQualifiedName").GetString(); @@ -365,7 +365,7 @@ public void ExportIntegration_OutputInMissingDirectory_CreatesDirectoryAndSuccee var fixtureRoot = FindSysMlModelsRoot(); Assert.NotNull(fixtureRoot); - var fixtureFile = Path.Combine(fixtureRoot!, "OMG", "examples", "VehicleExample", "VehicleDefinitions.sysml"); + var fixtureFile = Path.Combine(fixtureRoot, "OMG", "examples", "VehicleExample", "VehicleDefinitions.sysml"); Assert.True(File.Exists(fixtureFile), $"Could not find fixture file at {fixtureFile}"); var tempRoot = Path.Combine(Path.GetTempPath(), "sysml2tools-export-test-" + Guid.NewGuid().ToString("N")); @@ -402,7 +402,7 @@ public void ExportIntegration_OutputIsExistingDirectory_FailsCleanly() var fixtureRoot = FindSysMlModelsRoot(); Assert.NotNull(fixtureRoot); - var fixtureFile = Path.Combine(fixtureRoot!, "OMG", "examples", "VehicleExample", "VehicleDefinitions.sysml"); + var fixtureFile = Path.Combine(fixtureRoot, "OMG", "examples", "VehicleExample", "VehicleDefinitions.sysml"); Assert.True(File.Exists(fixtureFile), $"Could not find fixture file at {fixtureFile}"); var tempDir = Path.Combine(Path.GetTempPath(), "sysml2tools-export-test-" + Guid.NewGuid().ToString("N")); diff --git a/test/DemaConsulting.SysML2Tools.Tool.Tests/Query/QuerySubsystemTests.cs b/test/DemaConsulting.SysML2Tools.Tool.Tests/Query/QuerySubsystemTests.cs index 76f3b8a3..7667b8bb 100644 --- a/test/DemaConsulting.SysML2Tools.Tool.Tests/Query/QuerySubsystemTests.cs +++ b/test/DemaConsulting.SysML2Tools.Tool.Tests/Query/QuerySubsystemTests.cs @@ -481,7 +481,7 @@ package Model { json[json.IndexOf('{')..], QueryResultSerializerContext.Default.QueryResult); Assert.NotNull(deserialized); - Assert.Equal(2, deserialized!.Entries.Count); + Assert.Equal(2, deserialized.Entries.Count); Assert.Equal("Model::Beta", deserialized.Entries[0].QualifiedName); Assert.Equal("Model::Zeta", deserialized.Entries[1].QualifiedName); diff --git a/test/DemaConsulting.SysML2Tools.Tool.Tests/Query/QueryVerbsTests.cs b/test/DemaConsulting.SysML2Tools.Tool.Tests/Query/QueryVerbsTests.cs index 0409225b..924aa163 100644 --- a/test/DemaConsulting.SysML2Tools.Tool.Tests/Query/QueryVerbsTests.cs +++ b/test/DemaConsulting.SysML2Tools.Tool.Tests/Query/QueryVerbsTests.cs @@ -460,7 +460,7 @@ part def Car { json[jsonStart..], QueryResultSerializerContext.Default.QueryResult); Assert.NotNull(deserialized); - Assert.Contains("Metadata SoftwareInfo.isCritical: true", deserialized!.Summary); + Assert.Contains("Metadata SoftwareInfo.isCritical: true", deserialized.Summary); } ///