diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml
new file mode 100644
index 0000000..bd4d6db
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/question.yml
@@ -0,0 +1,82 @@
+---
+name: ❓ Question / Help
+description: Ask a usage question or get help with the TestResults library
+title: "[Question]: "
+labels: ["question"]
+assignees: []
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for reaching out! Please fill out the sections below so we can help you as quickly as possible.
+ For general discussion, you can also use
+ [GitHub Discussions](https://github.com/demaconsulting/TestResults/discussions).
+
+ - type: textarea
+ id: question
+ attributes:
+ label: Question
+ description: A clear and concise description of what you need help with.
+ placeholder: What would you like to know or understand?
+ validations:
+ required: true
+
+ - type: textarea
+ id: what-tried
+ attributes:
+ label: What Have You Tried?
+ description: Describe what you have already attempted, including any code or configuration you have used.
+ placeholder: |
+ ```csharp
+ // Your code here
+ ```
+ render: csharp
+
+ - type: textarea
+ id: expected
+ attributes:
+ label: Expected Outcome
+ description: A clear and concise description of what you expected to happen or what you are trying to achieve.
+ placeholder: Describe the outcome you are looking for...
+ validations:
+ required: true
+
+ - type: input
+ id: version
+ attributes:
+ label: Library Version
+ description: What version of the TestResults library are you using?
+ placeholder: e.g., 1.0.0
+ validations:
+ required: true
+
+ - type: dropdown
+ id: dotnet-version
+ attributes:
+ label: .NET Version
+ description: What version of .NET are you using?
+ options:
+ - ".NET 8"
+ - ".NET 9"
+ - ".NET 10"
+ - Other (please specify in additional context)
+ validations:
+ required: true
+
+ - type: textarea
+ id: additional-context
+ attributes:
+ label: Additional Context
+ description: Add any other context, screenshots, or links that may help answer your question.
+ placeholder: Any additional information...
+
+ - type: checkboxes
+ id: checklist
+ attributes:
+ label: Checklist
+ description: Please confirm the following
+ options:
+ - label: I have searched existing issues and discussions to ensure this has not been answered before
+ required: true
+ - label: I have provided a clear description of my question
+ required: true
diff --git a/.github/agents/test-developer.md b/.github/agents/test-developer.md
index fda2b4e..654277d 100644
--- a/.github/agents/test-developer.md
+++ b/.github/agents/test-developer.md
@@ -118,6 +118,15 @@ Common anti-patterns to avoid (not exhaustive):
// ✅ Good: Assert.HasCount(3, collection);
```
+5. **Avoid Assert.IsTrue for string prefix checks** - Use `Assert.StartsWith` instead of wrapping
+ `string.StartsWith` in `Assert.IsTrue`, as it produces clearer failure messages that show the expected prefix
+ and actual value:
+
+ ```csharp
+ // ❌ Bad: Assert.IsTrue(value.StartsWith("prefix"));
+ // ✅ Good: Assert.StartsWith("prefix", value);
+ ```
+
## Defer To
- **Requirements Agent**: For test strategy and coverage requirements
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 0283b56..43e409e 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -101,7 +101,7 @@ jobs:
strategy:
matrix:
- os: [windows-latest, ubuntu-latest]
+ os: [windows-latest, ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
@@ -137,8 +137,8 @@ jobs:
run: |
mkdir -p artifacts
echo "Capturing tool versions..."
- # Create short job ID: build-win, build-ubuntu
- OS_SHORT=$(echo "${{ matrix.os }}" | sed 's/windows-latest/win/;s/ubuntu-latest/ubuntu/')
+ # Create short job ID: build-windows, build-ubuntu, build-macos
+ OS_SHORT=$(echo "${{ matrix.os }}" | sed 's/-latest//')
JOB_ID="build-${OS_SHORT}"
dotnet versionmark --capture --job-id "${JOB_ID}" \
--output "artifacts/versionmark-${JOB_ID}.json" -- \
@@ -252,6 +252,7 @@ jobs:
uses: github/codeql-action/init@v4
with:
languages: csharp
+ build-mode: manual
queries: security-and-quality
config-file: ./.github/codeql-config.yml
diff --git a/AGENTS.md b/AGENTS.md
index 669a960..b00c0ef 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -1,277 +1,45 @@
-# AI Instructions for TestResults
+# Agent Quick Reference
-This file provides specific context and instructions for AI coding agents to
-interact effectively with this C# project.
+Project-specific guidance for agents working on TestResults - a lightweight C# library for
+programmatically creating test result files in TRX and JUnit formats.
-## Project Overview
+## Available Specialized Agents
-TestResults is a C# library for creating test result files. The library is designed to be:
+- **Requirements Agent** - Develops requirements and ensures test coverage linkage
+- **Technical Writer** - Creates accurate documentation following regulatory best practices
+- **Software Developer** - Writes production code in literate style
+- **Test Developer** - Creates unit tests following AAA pattern
+- **Code Quality Agent** - Enforces linting, static analysis, and security standards
+- **Repo Consistency Agent** - Ensures downstream repositories remain consistent with template patterns
-- **Lightweight**: Minimal external dependencies
-- **Simple**: Easy-to-use API for creating test result files
-- **Type-Safe**: Strongly-typed C# objects
-- **Cross-Platform**: Supports .NET 8, 9, and 10
+## Agent Selection Guide
-The library supports both TRX and JUnit XML formats, with potential for additional formats in the future.
+- Fix a bug → **Software Developer**
+- Add a new feature → **Requirements Agent** → **Software Developer** → **Test Developer**
+- Write a test → **Test Developer**
+- Fix linting or static analysis issues → **Code Quality Agent**
+- Update documentation → **Technical Writer**
+- Add or update requirements → **Requirements Agent**
+- Ensure test coverage linkage in `requirements.yaml` → **Requirements Agent**
+- Run security scanning or address CodeQL alerts → **Code Quality Agent**
+- Propagate template changes → **Repo Consistency Agent**
-## Technologies and Dependencies
+## Tech Stack
-### Runtime
+- C# 12, .NET 8.0/9.0/10.0, dotnet CLI, NuGet
-- **Language**: C# 12
-- **.NET Frameworks**: .NET 8, 9, and 10
-- **Primary Dependencies**: None currently
+## Key Files
-### Development Tools
+- **`requirements.yaml`** - All requirements with test linkage (enforced via `dotnet reqstream --enforce`)
+- **`.editorconfig`** - Code style (file-scoped namespaces, 4-space indent, UTF-8, LF endings)
+- **`.cspell.json`, `.markdownlint-cli2.jsonc`, `.yamllint.yaml`** - Linting configs
-- **Analyzers**: Microsoft.CodeAnalysis.NetAnalyzers and SonarAnalyzer.CSharp for static code analysis
-- **Source Control**: SourceLink for debugging support
-- **Testing**: MSTest framework with code coverage
-- **Requirements Management**: DemaConsulting.ReqStream for requirements tracking and traceability
-- **CI/CD**: GitHub Actions for build and release automation
-- **Code Quality**: SonarCloud for quality metrics
-- **Dependency Management**: Dependabot for automated dependency updates
+## Requirements
-## Project Structure
-
-The repository is organized as follows:
-
-```text
-/
-├── .config/ # .NET tool configurations
-├── .github/workflows/ # CI/CD pipeline configurations
-├── docs/ # Documentation source files
-│ ├── guide/ # Developer guide
-│ ├── requirements/ # Requirements specification
-│ └── tracematrix/ # Requirements trace matrix
-├── src/DemaConsulting.TestResults/ # Main library source code
-├── test/DemaConsulting.TestResults.Tests/ # Unit tests
-├── .editorconfig # Code style enforcement
-├── .cspell.json # Spell checking configuration
-├── .markdownlint.json # Markdown linting rules
-├── AGENTS.md # This file
-├── ARCHITECTURE.md # Architecture documentation
-├── CODE_OF_CONDUCT.md # Code of conduct
-├── CONTRIBUTING.md # Contribution guidelines
-├── DemaConsulting.TestResults.slnx # Visual Studio solution
-├── README.md # Main documentation
-└── requirements.yaml # Requirements definitions
-```
-
-Key directories:
-
-- **src/** - Contains the main library implementation
-- **test/** - Contains unit tests and test resources
-- **docs/** - Contains documentation source files and templates
-- **.github/** - Contains CI/CD workflows and automation
-
-Key files:
-
-- **requirements.yaml** - Defines the functional, quality, and documentation requirements
- for the library. All requirements should be traceable to test cases.
-
-## Development Commands
-
-Use these commands to perform common development tasks:
-
-### Initial Setup
-
-```bash
-# Restore .NET tools
-dotnet tool restore
-
-# Restore dependencies
-dotnet restore
-```
-
-### Building and Testing
-
-```bash
-# Build the project
-dotnet build
-
-# Build in release mode
-dotnet build --configuration Release
-
-# Run all tests
-dotnet test
-
-# Run tests with code coverage
-dotnet test --collect "XPlat Code Coverage"
-
-# Build NuGet package
-dotnet pack
-```
-
-### Quality Checks
-
-```bash
-# Run spell checker (requires npm install -g cspell)
-cspell "**/*.{md,cs}"
-
-# Run markdown linter (requires npm install -g markdownlint-cli)
-markdownlint "**/*.md"
-
-# Format code
-dotnet format
-
-# Verify formatting
-dotnet format --verify-no-changes
-```
-
-## Testing Guidelines
-
-### Test Organization
-
-- Tests are located under the `/test/DemaConsulting.TestResults.Tests/` folder
-- Use the MSTest framework (`[TestClass]`, `[TestMethod]`, etc.)
-- Test files should end with `.cs` and follow the naming convention `[Component]Tests.cs`
-
-### Test Structure
-
-- Use the AAA (Arrange, Act, Assert) pattern
-- Keep tests focused on a single behavior
-- Use descriptive test method names that explain what is being tested
-- **Test Naming Convention**: `ClassName_MethodUnderTest_Scenario_ExpectedBehavior`
- - `ClassName`: The name of the class being tested (e.g., `TrxSerializer`, `TestOutcome`)
- - `MethodUnderTest`: The method or property being tested (e.g., `Serialize`, `IsPassed`)
- - `Scenario`: The specific scenario or input condition (e.g., `BasicTestResults`, `PassedOutcome`)
- - `ExpectedBehavior`: The expected result (e.g., `ProducesValidTrxXml`, `ReturnsTrue`)
- - Example: `TrxSerializer_Serialize_BasicTestResults_ProducesValidTrxXml`
-
-### Test Coverage
-
-- All new features must have comprehensive unit tests
-- Aim for high code coverage (>80%)
-- Test both success and failure scenarios
-- Include edge cases and boundary conditions
-
-### Test Requirements
-
-- All tests must pass before merging
-- No warnings are allowed (warnings are treated as errors)
-- Tests should be isolated and not depend on execution order
-- Use appropriate assertions from MSTest (`Assert.AreEqual`, `Assert.ThrowsException`, etc.)
-
-## Code Style and Conventions
-
-### Naming Conventions
-
-- **PascalCase**: Classes, methods, properties, public fields, namespaces
-- **camelCase**: Local variables, private fields, parameters
-- **Interface names**: Start with 'I' (e.g., `ITestResult`)
-- **Test methods**: Follow `ClassName_MethodUnderTest_Scenario_ExpectedBehavior` pattern
- - Example: `TrxSerializer_Serialize_BasicTestResults_ProducesValidTrxXml`
-
-### Code Organization
-
-- One class per file (except for nested/related classes)
-- Organize using statements (System.* first, then others alphabetically)
-- Use file-scoped namespaces when appropriate
-- Group class members by type (fields, properties, constructors, methods)
-
-### Best Practices
-
-- **Nullable Reference Types**: Enabled at project level; use appropriately
-- **Warnings as Errors**: All warnings must be resolved
-- **XML Documentation**: Required for all public APIs
-- **Immutability**: Prefer readonly fields and get-only properties where appropriate
-- **LINQ**: Use LINQ for collection operations when it improves readability
-- **String Interpolation**: Prefer over string concatenation
-- **Object Initializers**: Use for cleaner object construction
-
-### Code Quality
-
-- Follow .editorconfig settings for consistent formatting
-- Use meaningful variable and method names
-- Keep methods focused and concise (Single Responsibility Principle)
-- Avoid code duplication (DRY principle)
-- Comment only when necessary to explain "why", not "what"
-- Use static analysis recommendations from analyzers
-
-## Quality Standards
-
-### Static Analysis
-
-- Microsoft.CodeAnalysis.NetAnalyzers is enabled in all projects for .NET-specific analysis
-- SonarAnalyzer.CSharp is enabled in all projects for additional code quality checks
-- All analyzer warnings must be addressed or explicitly suppressed with justification
-- Code style rules are enforced via .editorconfig
-
-### Documentation
-
-- All public APIs must have XML documentation comments
-- Include ``, ``, ``, and `` tags as appropriate
-- Keep documentation clear, concise, and accurate
-- Update README.md and ARCHITECTURE.md for significant changes
-
-### Spelling and Markdown
-
-- Use cspell for spell checking code and documentation
-- Follow markdownlint rules for markdown files
-- Add technical terms to .cspell.json dictionary as needed
-
-## CI/CD Pipeline
-
-### Build Process
-
-The build pipeline includes:
-
-1. **Quality Checks**: Run markdown linter, spell checker, and YAML linter
-2. **Checkout**: Clone the repository
-3. **Setup**: Install .NET SDKs (8, 9, 10)
-4. **Restore**: Restore tools and dependencies
-5. **SonarCloud Start**: Begin SonarCloud analysis (Linux only)
-6. **Build**: Compile in Release mode on both Windows and Linux
-7. **Test**: Run all tests with code coverage and generate TRX test result files
-8. **SonarCloud End**: Complete SonarCloud analysis (Linux only)
-9. **SBOM**: Generate Software Bill of Materials
-10. **Package**: Create NuGet packages
-11. **Build Documentation**:
- - Import requirements from requirements.yaml
- - Import TRX test results
- - Export requirements and trace matrix documents
- - Enforce requirements coverage
- - Generate PDF documentation (Developer Guide, Requirements, Trace Matrix)
-
-### Quality Gates
-
-All builds must pass:
-
-- Compilation with zero warnings
-- All unit tests passing
-- SonarCloud quality gate
-- Code coverage thresholds
-- Requirements coverage validation
-
-## Requirements Management
-
-The project uses DemaConsulting.ReqStream for requirements management and traceability.
-
-### Requirements File
-
-The `requirements.yaml` file defines all functional, quality, and documentation requirements for the library. Each requirement:
-
-- Has a unique identifier (e.g., REQ-FUNC-001)
-- Has a descriptive title
-- Is mapped to one or more test cases
-- Is organized into hierarchical sections
-
-### Requirements Process
-
-When working on this project:
-
-1. **Review Requirements**: Check `requirements.yaml` to understand existing requirements
-2. **Add New Requirements**: When adding significant new functionality, add corresponding requirements to `requirements.yaml`
-3. **Update Test Mappings**: Ensure all requirements reference the appropriate test cases
-4. **Verify Coverage**: The CI/CD pipeline enforces that all requirements are covered by passing tests
-
-### Requirements Documentation
-
-The build process generates:
-
-- **Requirements Specification PDF**: Complete requirements document
-- **Trace Matrix PDF**: Shows mapping between requirements and test cases with pass/fail status
+- All requirements MUST be linked to tests
+- Not all tests need to be linked to requirements (tests may exist for corner cases, design testing, failure-testing, etc.)
+- Enforced in CI: `dotnet reqstream --requirements requirements.yaml --tests "artifacts/**/*.trx" --enforce`
+- When adding features: add requirement + link to test
## Test Source Filters
@@ -287,247 +55,85 @@ evidence. This is critical for platform and framework requirements - **do not re
Without the source filter, a test result from any platform/framework satisfies the requirement. Adding the filter
ensures the CI evidence comes specifically from the required environment.
-## Common Tasks for AI Agents
-
-### Adding a New Feature
-
-1. Read ARCHITECTURE.md to understand the design
-2. Review requirements.yaml to see if a requirement exists for this feature
-3. If adding significant new functionality, add appropriate requirements to requirements.yaml
-4. Create or update the domain model classes
-5. Update serialization logic if needed
-6. Add comprehensive unit tests
-7. Update requirements.yaml to map requirements to new test cases
-8. Update XML documentation
-9. Update README.md with usage examples
-10. Run all tests and ensure they pass
-11. Complete pre-finalization quality checks (see below)
-
-### Fixing a Bug
+## Testing
-1. Reproduce the bug with a failing test
-2. Fix the bug with minimal changes
-3. Ensure the test now passes
-4. Verify no other tests are broken
-5. Update documentation if the bug fix changes behavior
-6. Complete pre-finalization quality checks (see below)
+- **Test Naming**: `ClassName_MethodUnderTest_Scenario_ExpectedBehavior` for unit tests
+- **Test Framework**: Uses MSTest for unit testing
+- **Code Coverage**: Maintain high code coverage for library APIs
-### Improving Code Quality
+## Code Style
-1. Run static analysis and address warnings
-2. Review code coverage reports
-3. Refactor duplicated code
-4. Improve naming and clarity
-5. Add missing documentation
-6. Verify all tests still pass
-7. Complete pre-finalization quality checks (see below)
+- **XML Docs**: Required on all public APIs with ``, ``, ``, `` tags
+- **Namespace**: File-scoped namespaces only
+- **Using Statements**: Top of file only (no nested using declarations except for IDisposable)
+- **String Formatting**: Use interpolated strings ($"") for clarity
+- **Warnings as Errors**: All analyzer warnings must be resolved
-### Updating Dependencies
-
-1. Check dependency versions in .csproj files
-2. Update to latest stable versions when appropriate
-3. Test thoroughly after updates
-4. Update documentation if APIs changed
-5. Complete pre-finalization quality checks (see below)
-
-## Pre-Finalization Quality Checks
+## Project Structure
-Before marking any task as complete and finalizing your session, you **MUST** run the following quality checks in this order:
+- **`src/DemaConsulting.TestResults/`** - Main library source code
+- **`test/DemaConsulting.TestResults.Tests/`** - Unit tests
+- **`docs/`** - Documentation source files (guide, requirements, tracematrix)
-### 1. Build and Test Validation
+## Build and Test
```bash
+# Restore tools and dependencies
+dotnet tool restore
+dotnet restore
+
# Build the project
dotnet build --configuration Release
-# Run all tests
+# Run unit tests
dotnet test --configuration Release
-```
-
-All builds must complete with zero warnings and all tests must pass.
-
-### 2. Code Review
-
-Use the **code_review** tool to get automated feedback on your changes:
-
-- Review all comments and suggestions
-- Address relevant feedback
-- If significant changes are made, run code_review again
-
-### 3. Security Scanning
-
-Use the **codeql_checker** tool to scan for security vulnerabilities:
-
-- This tool must be run after code_review is complete
-- Investigate all alerts discovered
-- Fix any alerts that require localized changes
-- Re-run codeql_checker after fixes to verify
-- Include a Security Summary with any unfixed vulnerabilities
-
-### Quality Check Workflow
-
-The complete workflow before task completion:
-
-1. Make code changes
-2. Run build and tests → Fix any issues
-3. Run code_review tool → Address relevant feedback
-4. Run codeql_checker tool → Fix security issues
-5. If significant changes were made, repeat steps 2-4
-6. Report progress with final commit
-7. Complete task
-
-**Note**: Only proceed to finalize your task after all quality checks pass and all issues are addressed.
-
-## Boundaries and Guardrails
-
-### What AI Agents Should NEVER Do
-
-- Modify files within `/obj/` or `/bin/` directories
-- Commit secrets, API keys, or sensitive configuration data
-- Make significant architectural changes without discussion
-- Remove or disable existing tests
-- Ignore or suppress analyzer warnings without justification
-- Add external runtime dependencies (the library must remain zero-dependency)
-
-### What AI Agents Should ALWAYS Do
-
-- Run tests before committing changes
-- Follow existing code style and patterns
-- Update documentation for user-facing changes
-- Add tests for new functionality
-- Resolve all warnings and analyzer suggestions
-- Keep changes minimal and focused
-- Complete all pre-finalization quality checks (build, test, code_review, codeql_checker) before marking work as complete
-
-### What AI Agents Should ASK About
-
-- Adding new public APIs or changing existing ones
-- Significant refactoring or architectural changes
-- Adding development dependencies
-- Changing build or release processes
-- Questions about requirements or expected behavior
-
-## Performance Considerations
-
-- The library is lightweight and should remain so
-- Avoid unnecessary allocations during serialization
-- Use efficient string handling (StringBuilder for concatenation)
-- Profile performance for large test result sets
-
-## Security Considerations
-- No file I/O operations within the library (caller controls file operations)
-- No network operations
-- Validate all inputs to public APIs
-- Be careful with XML serialization to avoid XXE attacks
-- Keep dependencies minimal to reduce security surface area
-
-## Tips for Effective Changes
-
-1. **Understand First**: Read existing code and documentation before making changes
-2. **Test Driven**: Write tests first or alongside code changes
-3. **Small Steps**: Make small, incremental changes that are easy to review
-4. **Run Often**: Build and test frequently during development
-5. **Document**: Update documentation as you change code
-6. **Review**: Self-review your changes before submitting
-
-## Getting Help
-
-- Review [ARCHITECTURE.md](ARCHITECTURE.md) for design details
-- Check [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines
-- Look at existing code for patterns and examples
-- Run `dotnet build` and `dotnet test` to verify changes
-- Use `dotnet --info` to check your environment
-
-## Version Support
-
-- The library targets .NET 8, 9, and 10
-- Use APIs available in all target frameworks
-- Test on multiple framework versions when possible
-- Check for framework-specific issues in CI/CD logs
-
-## Custom GitHub Copilot Agents
-
-This project has specialized GitHub Copilot agents to help with specific tasks. These agents
-are configured in the `.github/agents/` directory and can be invoked for their areas of expertise.
-
-### Available Agents
-
-#### Code Quality Agent (`@copilot[code-quality-agent]`)
-
-Ensures code quality through linting and static analysis:
-
-- Running and fixing linting issues (markdown, YAML, spell check, code formatting)
-- Ensuring static analysis passes with zero warnings
-- Verifying code security
-- Enforcing quality gates before merging
-
-**Use this agent for**: Code reviews, linting fixes, static analysis, quality gate enforcement.
-
-#### Repo Consistency Agent (`@copilot[repo-consistency-agent]`)
-
-Ensures this repository remains consistent with the TemplateDotNetLibrary template:
-
-- Reviewing repository structure against the template
-- Identifying drift from template standards
-- Recommending updates to bring the project back in sync
-
-**Use this agent for**: Periodic consistency reviews, checking for template drift, adopting new template patterns.
-
-#### Requirements Agent (`@copilot[requirements-agent]`)
-
-Develops requirements and ensures appropriate test coverage:
-
-- Creating and reviewing requirements in `requirements.yaml`
-- Ensuring requirements have appropriate test coverage
-- Differentiating requirements from design details
-
-**Use this agent for**: Adding new requirements, reviewing requirement quality, test linkage strategy.
-
-#### Software Developer (`@copilot[software-developer]`)
-
-Writes production code with emphasis on testability and clarity:
-
-- Implementing production code features
-- Code refactoring for testability and maintainability
-- Implementing library APIs and functionality
-
-**Use this agent for**: Feature implementation, bug fixes, refactoring production code.
-
-#### Technical Writer (`@copilot[technical-writer]`)
+# Run tests with code coverage
+dotnet test --collect "XPlat Code Coverage"
+```
-Creates and maintains clear, accurate, and complete documentation:
+## Documentation
-- Creating or updating project documentation (README, guides, CONTRIBUTING, etc.)
-- Ensuring documentation accuracy and completeness
-- Markdown and spell checking compliance
+- **User Guide**: `docs/guide/guide.md`
+- **Requirements**: `requirements.yaml` -> auto-generated docs
+- **Build Notes**: Auto-generated via BuildMark
+- **Code Quality**: Auto-generated via CodeQL and SonarMark
+- **Trace Matrix**: Auto-generated via ReqStream
+- **CHANGELOG.md**: Not present - changes are captured in the auto-generated build notes
-**Use this agent for**: Documentation updates, API comments, usage examples, and documentation fixes.
+## Markdown Link Style
-#### Test Developer (`@copilot[test-developer]`)
+- **AI agent markdown files** (`.github/agents/*.md`): Use inline links `[text](url)` so URLs are visible in agent context
+- **README.md**: Use absolute URLs (shipped in NuGet package)
+- **All other markdown files**: Use reference-style links `[text][ref]` with `[ref]: url` at document end
-Writes unit and integration tests following the AAA pattern:
+## CI/CD
-- Creating unit tests for individual components
-- Improving test coverage
-- Refactoring existing tests for clarity
+- **Quality Checks**: Markdown lint, spell check, YAML lint
+- **Build**: Multi-platform (Windows/Linux/macOS)
+- **CodeQL**: Security scanning
+- **Documentation**: Auto-generated via Pandoc + Weasyprint
-**Use this agent for**: Writing new tests, improving test coverage, refactoring test code.
+## Common Tasks
-### Using Custom Agents
+```bash
+# Format code
+dotnet format
-Invoke agents in issues and pull requests by mentioning them:
+# Verify formatting
+dotnet format --verify-no-changes
-```markdown
-@copilot[technical-writer] Please update the README with examples for the new feature.
+# Build NuGet package
+dotnet pack --configuration Release
```
-```markdown
-@copilot[code-quality-agent] Review this PR for code quality standards.
-```
+## Agent Report Files
-```markdown
-@copilot[repo-consistency-agent] Please check if this repository is consistent with the template.
-```
+When agents need to write report files to communicate with each other or the user, follow these guidelines:
-For detailed information about each agent, see their individual files in the `.github/agents/` directory.
+- **Naming Convention**: Use the pattern `AGENT_REPORT_xxxx.md` (e.g., `AGENT_REPORT_analysis.md`, `AGENT_REPORT_results.md`)
+- **Purpose**: These files are for temporary inter-agent communication and should not be committed
+- **Exclusions**: Files matching `AGENT_REPORT_*.md` are automatically:
+ - Excluded from git (via .gitignore)
+ - Excluded from markdown linting
+ - Excluded from spell checking
diff --git a/src/DemaConsulting.TestResults/DemaConsulting.TestResults.csproj b/src/DemaConsulting.TestResults/DemaConsulting.TestResults.csproj
index 72e84ff..c487c8f 100644
--- a/src/DemaConsulting.TestResults/DemaConsulting.TestResults.csproj
+++ b/src/DemaConsulting.TestResults/DemaConsulting.TestResults.csproj
@@ -36,6 +36,9 @@
true
latest
+
+ true
+
true
$(PackageId)
@@ -46,6 +49,7 @@
+
@@ -66,6 +70,10 @@
+
+
+
+
diff --git a/src/DemaConsulting.TestResults/IO/JUnitSerializer.cs b/src/DemaConsulting.TestResults/IO/JUnitSerializer.cs
index 1e488a8..f3f1fef 100644
--- a/src/DemaConsulting.TestResults/IO/JUnitSerializer.cs
+++ b/src/DemaConsulting.TestResults/IO/JUnitSerializer.cs
@@ -58,7 +58,7 @@ public static class JUnitSerializer
public static string Serialize(TestResults results)
{
// Validate input
- _ = results ?? throw new ArgumentNullException(nameof(results));
+ ArgumentNullException.ThrowIfNull(results);
// Group test results by class name for test suites
var testSuites = results.Results
@@ -199,15 +199,13 @@ private static XElement CreateFailureOrErrorElement(string elementName, TestResu
///
/// JUnit XML File Contents
/// Test Results
- /// Thrown when junitContents is null or whitespace
+ /// Thrown when junitContents is null
+ /// Thrown when junitContents is whitespace
/// Thrown when the XML structure is invalid
public static TestResults Deserialize(string junitContents)
{
// Validate input
- if (string.IsNullOrWhiteSpace(junitContents))
- {
- throw new ArgumentException("JUnit contents cannot be null or whitespace", nameof(junitContents));
- }
+ ArgumentException.ThrowIfNullOrWhiteSpace(junitContents);
// Parse the document
var doc = XDocument.Parse(junitContents);
diff --git a/src/DemaConsulting.TestResults/IO/Serializer.cs b/src/DemaConsulting.TestResults/IO/Serializer.cs
index 06914f2..eb9b582 100644
--- a/src/DemaConsulting.TestResults/IO/Serializer.cs
+++ b/src/DemaConsulting.TestResults/IO/Serializer.cs
@@ -106,15 +106,13 @@ public static TestResultFormat Identify(string contents)
///
/// The test result file contents
/// Deserialized test results
- /// Thrown when contents is null or whitespace
+ /// Thrown when contents is null
+ /// Thrown when contents is whitespace
/// Thrown when format cannot be identified or deserialization fails
public static TestResults Deserialize(string contents)
{
// Validate input
- if (string.IsNullOrWhiteSpace(contents))
- {
- throw new ArgumentException("Test result contents cannot be null or whitespace", nameof(contents));
- }
+ ArgumentException.ThrowIfNullOrWhiteSpace(contents);
// Identify the format
var format = Identify(contents);
diff --git a/src/DemaConsulting.TestResults/IO/TrxSerializer.cs b/src/DemaConsulting.TestResults/IO/TrxSerializer.cs
index c649c16..e448ee3 100644
--- a/src/DemaConsulting.TestResults/IO/TrxSerializer.cs
+++ b/src/DemaConsulting.TestResults/IO/TrxSerializer.cs
@@ -75,7 +75,7 @@ public static class TrxSerializer
public static string Serialize(TestResults results)
{
// Validate input
- _ = results ?? throw new ArgumentNullException(nameof(results));
+ ArgumentNullException.ThrowIfNull(results);
// Construct the document
var doc = new XDocument();
@@ -303,15 +303,13 @@ private static XElement CreateSummaryElement(List testResults)
///
/// TRX File Contents
/// Test Results
- /// Thrown when trxContents is null or whitespace
+ /// Thrown when trxContents is null
+ /// Thrown when trxContents is whitespace
/// Thrown when the TRX structure is invalid
public static TestResults Deserialize(string trxContents)
{
// Validate input
- if (string.IsNullOrWhiteSpace(trxContents))
- {
- throw new ArgumentException("TRX contents cannot be null or whitespace", nameof(trxContents));
- }
+ ArgumentException.ThrowIfNullOrWhiteSpace(trxContents);
// Parse the document
var doc = XDocument.Parse(trxContents);
diff --git a/test/DemaConsulting.TestResults.Tests/AssemblyInfo.cs b/test/DemaConsulting.TestResults.Tests/AssemblyInfo.cs
index e6b2ffe..03fa5d7 100644
--- a/test/DemaConsulting.TestResults.Tests/AssemblyInfo.cs
+++ b/test/DemaConsulting.TestResults.Tests/AssemblyInfo.cs
@@ -20,4 +20,5 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
+[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("DynamicProxyGenAssembly2")]
[assembly: Parallelize(Workers = 0, Scope = ExecutionScope.MethodLevel)]
diff --git a/test/DemaConsulting.TestResults.Tests/DemaConsulting.TestResults.Tests.csproj b/test/DemaConsulting.TestResults.Tests/DemaConsulting.TestResults.Tests.csproj
index 15a934c..1eeffd8 100644
--- a/test/DemaConsulting.TestResults.Tests/DemaConsulting.TestResults.Tests.csproj
+++ b/test/DemaConsulting.TestResults.Tests/DemaConsulting.TestResults.Tests.csproj
@@ -24,6 +24,11 @@
+
+
+
+
+