Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 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
2 changes: 2 additions & 0 deletions .reviewmark.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,10 @@ reviews:
- id: TestResults-IO-SerializerHelpers
title: Review that TestResults IO SerializerHelpers Implementation is Correct
paths:
- "docs/reqstream/test-results-library/io/serializer-helpers.yaml"
- "docs/design/test-results-library/io/serializer-helpers.md"
- "src/DemaConsulting.TestResults/IO/SerializerHelpers.cs"
- "test/DemaConsulting.TestResults.Tests/IO/SerializerHelpersTests.cs"

- id: TestResults-IO-TrxSerializer
title: Review that TestResults IO TrxSerializer Implementation is Correct
Expand Down
21 changes: 6 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ The library supports the following test outcomes:
- `Passed` - Test passed successfully
- `PassedButRunAborted` - Test passed but the run was aborted
- `Warning` - Test passed with warnings
- `Completed` - Test completed successfully

**Failure Outcomes:**

Expand All @@ -180,6 +179,7 @@ The library supports the following test outcomes:

**Other Outcomes:**

- `Completed` - Test completed successfully
- `Inconclusive` - Test result was inconclusive
- `Disconnected` - Test was disconnected
- `InProgress` - Test is currently in progress
Expand Down Expand Up @@ -230,24 +230,15 @@ dotnet test

For convenience, the repository includes helper scripts to streamline development:

**Windows:**

```bash
# Build and test the project
build.bat
pwsh ./build.ps1

# Run code formatting, spelling, and markdown checks
lint.bat
```

**Linux/macOS:**
pwsh ./lint.ps1

```bash
# Build and test the project
./build.sh

# Run code formatting, spelling, and markdown checks
./lint.sh
# Auto-fix formatting issues
pwsh ./fix.ps1
```

**Visual Studio Code:**
Expand Down Expand Up @@ -306,6 +297,6 @@ Developed and maintained by [DEMA Consulting](https://github.com/demaconsulting)
[link-nuget]: https://www.nuget.org/packages/DemaConsulting.TestResults

<!-- Document References -->
[architecture]: https://github.com/demaconsulting/TestResults/blob/main/ARCHITECTURE.md
[architecture]: https://github.com/demaconsulting/TestResults/blob/main/docs/design/introduction.md
[contributing]: https://github.com/demaconsulting/TestResults/blob/main/CONTRIBUTING.md
[code-of-conduct]: https://github.com/demaconsulting/TestResults/blob/main/CODE_OF_CONDUCT.md
42 changes: 40 additions & 2 deletions docs/design/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,43 @@ src/DemaConsulting.TestResults/
└── TestResults.cs — Collection of test results (TestResults unit)
```

[user-guide]: https://github.com/demaconsulting/TestResults
[requirements-doc]: https://github.com/demaconsulting/TestResults
## Companion Artifact Structure

Each design unit has corresponding artifacts across requirements, source, tests, and
review-set entries, forming end-to-end traceability:

Comment thread
Malcolmnixon marked this conversation as resolved.
```text
requirements.yaml — System-level requirements (TestResults-*)
docs/reqstream/test-results-library/ — Unit-level requirements
Comment thread
Malcolmnixon marked this conversation as resolved.
├── io/
│ ├── io.yaml — IO Subsystem requirements
│ ├── serializer.yaml — Serializer unit requirements
│ ├── serializer-helpers.yaml — SerializerHelpers unit requirements
│ ├── trx-serializer.yaml — TrxSerializer unit requirements
│ └── junit-serializer.yaml — JUnitSerializer unit requirements
├── test-outcome.yaml — TestOutcome unit requirements
├── test-result.yaml — TestResult unit requirements
└── test-results.yaml — TestResults unit requirements
docs/design/ — Design documentation (this document and sub-documents)
├── test-results-library/
│ ├── io/ — IO Subsystem design
│ ├── test-outcome.md — TestOutcome unit design
│ ├── test-result.md — TestResult unit design
│ └── test-results.md — TestResults unit design
src/DemaConsulting.TestResults/ — Source implementation
└── IO/
├── Serializer.cs
├── SerializerHelpers.cs
├── TrxSerializer.cs
└── JUnitSerializer.cs
test/DemaConsulting.TestResults.Tests/ — Unit tests
└── IO/
├── IOTests.cs
├── SerializerTests.cs
├── SerializerHelpersTests.cs
├── TrxSerializerTests.cs
└── JUnitSerializerTests.cs
```

[user-guide]: https://github.com/demaconsulting/TestResults/blob/main/docs/user_guide/introduction.md
[requirements-doc]: https://github.com/demaconsulting/TestResults/blob/main/requirements.yaml
6 changes: 3 additions & 3 deletions docs/design/test-results-library/io/serializer.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,6 @@ pass the raw content and receive a `TestResults` object.

## SerializerHelpers Dependency

The `Serializer.Deserialize()` method delegates writing to format-specific serializers
that depend on the [SerializerHelpers](serializer-helpers.md) unit for UTF-8 output
encoding. See [serializer-helpers.md](serializer-helpers.md) for details.
The `TrxSerializer.Serialize()` and `JUnitSerializer.Serialize()` methods both depend
on the [SerializerHelpers](serializer-helpers.md) unit for UTF-8 output encoding.
See [serializer-helpers.md](serializer-helpers.md) for details.
2 changes: 1 addition & 1 deletion docs/reqstream/test-results-library/io/io.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# This file covers the IO subsystem of the TestResults library.
# Unit-level requirements are in the individual unit files:
# - serializer.yaml
# - serializer-helpers.yaml
# - trx-serializer.yaml
# - junit-serializer.yaml
Comment thread
Malcolmnixon marked this conversation as resolved.

Expand Down Expand Up @@ -49,6 +48,7 @@ sections:
children:
- TestResults-Trx-Serialize
- TestResults-JUnit-Serialize
- TestResults-SerializerHelpers-Utf8Encoding
tests:
- IO_Serialize_TestResults_ProducesTrxContent
- IO_Serialize_TestResults_ProducesJUnitContent
31 changes: 31 additions & 0 deletions docs/reqstream/test-results-library/io/serializer-helpers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
# Software Unit Requirements for the SerializerHelpers Unit
#
# DERIVATION NOTE: These requirements are a top-down decomposition of
# TestResults-IO-Serialize (io.yaml). The IO subsystem's obligation to produce
# correctly-encoded XML serialized output decomposes into three sibling unit
# responsibilities: TrxSerializer, JUnitSerializer, and SerializerHelpers.
# SerializerHelpers satisfies the shared encoding constraint that both XML
# serializer units depend on.
#
# These requirements were NOT derived from or driven by the existing
# implementation. The need for a correct UTF-8 encoding declaration is an
# interoperability constraint placed on the IO subsystem by downstream XML
# consumers; SerializerHelpers is the unit that satisfies that constraint
# on behalf of both serializer units.

sections:
- title: SerializerHelpers Unit Requirements
requirements:
- id: TestResults-SerializerHelpers-Utf8Encoding
title: The SerializerHelpers unit shall provide a string writer that reports UTF-8 as its character encoding.
justification: |
XML serializers read the encoding reported by their underlying string writer to
determine which encoding declaration to emit in the XML prolog. The IO subsystem
must produce XML output that declares encoding="UTF-8" so that downstream tools
correctly interpret the byte stream. The default StringWriter reports UTF-16, which
would produce an incorrect declaration. This unit satisfies the encoding constraint
shared by both TrxSerializer and JUnitSerializer by providing a writer that correctly
reports UTF-8, decomposing the TestResults-IO-Serialize obligation.
Comment thread
Malcolmnixon marked this conversation as resolved.
Outdated
tests:
- Utf8StringWriter_Encoding_ReturnsUtf8
1 change: 1 addition & 0 deletions requirements.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ includes:
- docs/reqstream/test-results-library/test-result.yaml
- docs/reqstream/test-results-library/io/io.yaml
- docs/reqstream/test-results-library/io/serializer.yaml
- docs/reqstream/test-results-library/io/serializer-helpers.yaml
- docs/reqstream/test-results-library/io/trx-serializer.yaml
- docs/reqstream/test-results-library/io/junit-serializer.yaml
- docs/reqstream/test-results-library/platform-requirements.yaml
Expand Down
15 changes: 13 additions & 2 deletions src/DemaConsulting.TestResults/IO/SerializerHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,23 @@
namespace DemaConsulting.TestResults.IO;

/// <summary>
/// String writer that uses UTF-8 encoding
/// String writer that reports UTF-8 as its encoding.
/// </summary>
/// <remarks>
/// <see cref="System.Xml.XmlWriter"/> reads the <see cref="System.IO.TextWriter.Encoding"/>
/// property of the underlying writer to determine which encoding declaration to emit in the
/// XML prolog. The default <see cref="StringWriter"/> reports UTF-16 (the .NET in-memory
/// string encoding), which would cause serializers to write <c>encoding="utf-16"</c> even
/// when the resulting string is later consumed or stored as UTF-8. This class overrides
/// <see cref="Encoding"/> to return <see cref="System.Text.Encoding.UTF8"/> so that the
/// XML declaration correctly declares <c>encoding="UTF-8"</c>.
Comment thread
Malcolmnixon marked this conversation as resolved.
Outdated
/// </remarks>
internal sealed class Utf8StringWriter : StringWriter
{
/// <summary>
/// Gets the UTF-8 encoding
/// Gets the UTF-8 encoding, overriding the default UTF-16 reported by
/// <see cref="StringWriter"/> so that XML serializers emit the correct
/// <c>encoding="UTF-8"</c> declaration in the XML prolog.
/// </summary>
public override Encoding Encoding => Encoding.UTF8;
}
48 changes: 48 additions & 0 deletions test/DemaConsulting.TestResults.Tests/IO/SerializerHelpersTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright(c) 2025 DEMA Consulting
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

using System.Text;
using DemaConsulting.TestResults.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace DemaConsulting.TestResults.Tests.IO;

/// <summary>
/// Tests for SerializerHelpers unit
/// </summary>
[TestClass]
public sealed class SerializerHelpersTests
{
/// <summary>
/// Test that Utf8StringWriter reports UTF-8 as its encoding
/// </summary>
[TestMethod]
public void Utf8StringWriter_Encoding_ReturnsUtf8()
{
// Arrange: create a Utf8StringWriter
using var writer = new Utf8StringWriter();

// Act: read the reported encoding
var encoding = writer.Encoding;

// Assert: encoding is UTF-8
Assert.AreEqual(Encoding.UTF8, encoding);
}
}
Loading