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 @@ + + + + +