Skip to content

Commit 454e194

Browse files
Add additional coverage tests for core ReqIF types
1 parent eb66a73 commit 454e194

2 files changed

Lines changed: 423 additions & 0 deletions

File tree

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
// -------------------------------------------------------------------------------------------------
2+
// <copyright file="AdditionalCoverageTestFixture.cs" company="Starion Group S.A.">
3+
//
4+
// Copyright 2017-2025 Starion Group S.A.
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// </copyright>
19+
// -------------------------------------------------------------------------------------------------
20+
21+
namespace ReqIFSharp.Tests.AdditionalCoverage
22+
{
23+
using System;
24+
using System.IO;
25+
using System.Linq;
26+
using System.Text;
27+
using System.Threading;
28+
using System.Threading.Tasks;
29+
using System.Xml;
30+
31+
using NUnit.Framework;
32+
33+
using ReqIFSharp;
34+
35+
/// <summary>
36+
/// Additional tests that exercise asynchronous and fallback behaviour in several core classes.
37+
/// </summary>
38+
[TestFixture]
39+
public class AdditionalCoverageTestFixture
40+
{
41+
[Test]
42+
public void RelationGroup_ReadXml_CreatesFallbacksForMissingReferences()
43+
{
44+
var content = new ReqIFContent();
45+
var relationGroupType = new RelationGroupType(content, null) { Identifier = "rgt" };
46+
47+
var existingSpecification = new Specification(content, null)
48+
{
49+
Identifier = "existing-spec"
50+
};
51+
52+
var existingRelation = new SpecRelation(content, null)
53+
{
54+
Identifier = "existing-rel"
55+
};
56+
57+
var relationGroup = new RelationGroup(content, null)
58+
{
59+
Identifier = "rg",
60+
LastChange = new DateTime(2024, 1, 1, 12, 0, 0, DateTimeKind.Utc)
61+
};
62+
63+
var xml = $@"<RELATION-GROUP IDENTIFIER=""rg"" LAST-CHANGE=""2024-01-01T12:00:00Z"" IS-EDITABLE=""true"">
64+
<TYPE>
65+
<RELATION-GROUP-TYPE-REF>{relationGroupType.Identifier}</RELATION-GROUP-TYPE-REF>
66+
</TYPE>
67+
<SOURCE-SPECIFICATION>
68+
<SPECIFICATION-REF>missing-spec</SPECIFICATION-REF>
69+
</SOURCE-SPECIFICATION>
70+
<TARGET-SPECIFICATION>
71+
<SPECIFICATION-REF>{existingSpecification.Identifier}</SPECIFICATION-REF>
72+
</TARGET-SPECIFICATION>
73+
<SPEC-RELATIONS>
74+
<SPEC-RELATION-REF>{existingRelation.Identifier}</SPEC-RELATION-REF>
75+
<SPEC-RELATION-REF>missing-rel</SPEC-RELATION-REF>
76+
</SPEC-RELATIONS>
77+
</RELATION-GROUP>";
78+
79+
using var reader = XmlReader.Create(new StringReader(xml));
80+
reader.MoveToContent();
81+
82+
relationGroup.ReadXml(reader);
83+
84+
Assert.Multiple(() =>
85+
{
86+
Assert.That(relationGroup.IsEditable, Is.True, "IS-EDITABLE attribute should enable editing");
87+
Assert.That(relationGroup.Type, Is.SameAs(relationGroupType));
88+
Assert.That(relationGroup.SourceSpecification, Is.Not.Null, "Fallback specification should be created");
89+
Assert.That(relationGroup.SourceSpecification.Identifier, Is.EqualTo("missing-spec"));
90+
Assert.That(relationGroup.TargetSpecification, Is.SameAs(existingSpecification));
91+
Assert.That(relationGroup.SpecRelations.Count, Is.EqualTo(2));
92+
Assert.That(relationGroup.SpecRelations.SingleOrDefault(x => ReferenceEquals(x, existingRelation)), Is.Not.Null);
93+
Assert.That(relationGroup.SpecRelations.Any(x => x.Identifier == "missing-rel" && x.Description != null), Is.True);
94+
});
95+
}
96+
97+
[Test]
98+
public async Task RelationGroup_ReadXmlAsync_CreatesFallbacksForMissingReferences()
99+
{
100+
var content = new ReqIFContent();
101+
_ = new RelationGroupType(content, null) { Identifier = "rgt" };
102+
_ = new Specification(content, null) { Identifier = "existing-spec" };
103+
_ = new SpecRelation(content, null) { Identifier = "existing-rel" };
104+
105+
var relationGroup = new RelationGroup(content, null) { Identifier = "rg" };
106+
107+
var xml = "<RELATION-GROUP IDENTIFIER=\"rg\"><TYPE><RELATION-GROUP-TYPE-REF>rgt</RELATION-GROUP-TYPE-REF></TYPE>"
108+
+ "<SOURCE-SPECIFICATION><SPECIFICATION-REF>missing-spec</SPECIFICATION-REF></SOURCE-SPECIFICATION>"
109+
+ "<TARGET-SPECIFICATION><SPECIFICATION-REF>existing-spec</SPECIFICATION-REF></TARGET-SPECIFICATION>"
110+
+ "<SPEC-RELATIONS><SPEC-RELATION-REF>existing-rel</SPEC-RELATION-REF>"
111+
+ "<SPEC-RELATION-REF>missing-rel</SPEC-RELATION-REF></SPEC-RELATIONS></RELATION-GROUP>";
112+
113+
using var reader = XmlReader.Create(new StringReader(xml), new XmlReaderSettings { Async = true });
114+
await reader.MoveToContentAsync();
115+
116+
await relationGroup.ReadXmlAsync(reader, CancellationToken.None);
117+
118+
Assert.That(relationGroup.SpecRelations.Count, Is.EqualTo(2));
119+
}
120+
121+
[Test]
122+
public async Task SpecHierarchy_ReadXmlAsync_InitialisesContainerAndChildren()
123+
{
124+
var content = new ReqIFContent();
125+
var rootSpecification = new Specification(content, null) { Identifier = "root" };
126+
var existingObject = new SpecObject(content, null) { Identifier = "existing-object" };
127+
128+
var hierarchy = new SpecHierarchy(rootSpecification, content, null)
129+
{
130+
Identifier = "hierarchy"
131+
};
132+
133+
var xml = $@"<SPEC-HIERARCHY IDENTIFIER=""hierarchy"" IS-TABLE-INTERNAL=""true"">
134+
<OBJECT>
135+
<SPEC-OBJECT-REF>missing-object</SPEC-OBJECT-REF>
136+
</OBJECT>
137+
<CHILDREN>
138+
<SPEC-HIERARCHY IDENTIFIER=""child"">
139+
<OBJECT>
140+
<SPEC-OBJECT-REF>{existingObject.Identifier}</SPEC-OBJECT-REF>
141+
</OBJECT>
142+
</SPEC-HIERARCHY>
143+
</CHILDREN>
144+
</SPEC-HIERARCHY>";
145+
146+
using var reader = XmlReader.Create(new StringReader(xml), new XmlReaderSettings { Async = true });
147+
await reader.MoveToContentAsync();
148+
149+
await hierarchy.ReadXmlAsync(reader, CancellationToken.None);
150+
151+
Assert.Multiple(() =>
152+
{
153+
Assert.That(hierarchy.IsTableInternal, Is.True);
154+
Assert.That(hierarchy.Object, Is.Null, "Missing objects should yield null reference");
155+
Assert.That(hierarchy.Children, Has.Count.EqualTo(1));
156+
Assert.That(hierarchy.Children[0].Object, Is.SameAs(existingObject));
157+
Assert.That(hierarchy.Children[0].Container, Is.SameAs(hierarchy));
158+
});
159+
}
160+
161+
[Test]
162+
public void ReqIF_WriteXml_AddsXhtmlNamespaceWhenDatatypePresent()
163+
{
164+
var reqIf = CreateReqIfDocument();
165+
166+
var builder = new StringBuilder();
167+
using (var writer = XmlWriter.Create(builder, new XmlWriterSettings { OmitXmlDeclaration = true }))
168+
{
169+
writer.WriteStartElement("REQ-IF");
170+
reqIf.WriteXml(writer);
171+
writer.WriteEndElement();
172+
}
173+
174+
var xml = builder.ToString();
175+
176+
StringAssert.Contains("xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"", xml);
177+
StringAssert.Contains("REQ-IF-HEADER", xml);
178+
StringAssert.Contains("TOOL-EXTENSIONS", xml);
179+
}
180+
181+
[Test]
182+
public async Task ReqIF_ReadXmlAsync_RestoresHeaderAndToolExtensions()
183+
{
184+
var reqIf = CreateReqIfDocument();
185+
186+
var builder = new StringBuilder();
187+
using (var writer = XmlWriter.Create(builder, new XmlWriterSettings { OmitXmlDeclaration = true }))
188+
{
189+
writer.WriteStartElement("REQ-IF");
190+
reqIf.WriteXml(writer);
191+
writer.WriteEndElement();
192+
}
193+
194+
using var reader = XmlReader.Create(new StringReader(builder.ToString()), new XmlReaderSettings { Async = true });
195+
await reader.MoveToContentAsync();
196+
197+
var roundTrip = new ReqIF();
198+
await roundTrip.ReadXmlAsync(reader, CancellationToken.None);
199+
200+
Assert.Multiple(() =>
201+
{
202+
Assert.That(roundTrip.Lang, Is.EqualTo(reqIf.Lang));
203+
Assert.That(roundTrip.TheHeader.Title, Is.EqualTo(reqIf.TheHeader.Title));
204+
Assert.That(roundTrip.ToolExtension, Has.Count.EqualTo(1));
205+
Assert.That(roundTrip.CoreContent.DataTypes.Count, Is.EqualTo(2));
206+
});
207+
}
208+
209+
[Test]
210+
public void AttributeValueXhtml_ExtractsPlainTextAndDetectsExternalObjects()
211+
{
212+
var attributeValue = new AttributeValueXHTML();
213+
attributeValue.TheValue = "<div>plain <b>text</b><object data=\"file%20name.bin\" type=\"application/octet-stream\"></object></div>";
214+
215+
var plain = attributeValue.ExtractUnformattedTextFromValue();
216+
217+
Assert.That(plain, Is.EqualTo("plain text"));
218+
219+
var objects = attributeValue.ExternalObjects;
220+
Assert.That(objects, Has.Count.EqualTo(1));
221+
Assert.That(objects[0].Uri, Is.EqualTo("file name.bin"));
222+
}
223+
224+
private static ReqIF CreateReqIfDocument()
225+
{
226+
var reqIf = new ReqIF
227+
{
228+
Lang = "en",
229+
TheHeader = new ReqIFHeader
230+
{
231+
Identifier = "header",
232+
Comment = "comment",
233+
CreationTime = new DateTime(2024, 01, 01, 12, 00, 00, DateTimeKind.Utc),
234+
RepositoryId = "repo",
235+
ReqIFToolId = "tool",
236+
ReqIFVersion = "1.0",
237+
SourceToolId = "source",
238+
Title = "title"
239+
},
240+
CoreContent = new ReqIFContent()
241+
};
242+
243+
var enumeration = new DatatypeDefinitionEnumeration(reqIf.CoreContent, null)
244+
{
245+
Identifier = "enum"
246+
};
247+
248+
var enumValue = new EnumValue(enumeration, null)
249+
{
250+
Identifier = "enum-value"
251+
};
252+
253+
_ = new EmbeddedValue(enumValue, null)
254+
{
255+
Key = 5,
256+
OtherContent = "red"
257+
};
258+
259+
var xhtmlDatatype = new DatatypeDefinitionXHTML(reqIf.CoreContent, null)
260+
{
261+
Identifier = "xhtml"
262+
};
263+
264+
reqIf.ToolExtension.Add(new ReqIFToolExtension { InnerXml = "<extension />" });
265+
266+
return reqIf;
267+
}
268+
}
269+
}

0 commit comments

Comments
 (0)