|
| 1 | +### RestSharp – Developer Notes (agents.md) |
| 2 | + |
| 3 | +#### Scope |
| 4 | +This document captures project-specific knowledge to speed up advanced development and maintenance of RestSharp. It focuses on build, configuration, and testing details unique to this repository, plus conventions and tips that help avoid common pitfalls. |
| 5 | + |
| 6 | +--- |
| 7 | + |
| 8 | +### Build and configuration |
| 9 | + |
| 10 | +- Solution layout |
| 11 | + - Root solution: `RestSharp.sln`. |
| 12 | + - Library sources in `src/RestSharp` targeting multiple frameworks via shared props. |
| 13 | + - Tests live under `test/` and are multi-targeted (see below). |
| 14 | + |
| 15 | +- Multi-targeting |
| 16 | + - Tests target: `net48; net8.0; net9.0; net10.0` (defined in `test/Directory.Build.props`). |
| 17 | + - .NET Framework 4.8 support is provided via `Microsoft.NETFramework.ReferenceAssemblies.net472` for reference assemblies during build when `TargetFramework == net48`. |
| 18 | + - CI uses `actions/setup-dotnet@v4` with `dotnet-version: 9.0.x` for packaging; building tests locally may require multiple SDKs if you intend to run against all TFMs. Practically, you can run on a single installed TFM by overriding `-f`. |
| 19 | + - CI for pull requests runs tests against the supported .NET versions (.NET 8, .NET 9, and .NET 10) on Linux and Windows. On Windows, it also runs tests against .NET Framework 4.8. |
| 20 | + |
| 21 | +- Central props |
| 22 | + - `test/Directory.Build.props` imports `props/Common.props` from the repo root. This propagates common settings into all test projects. |
| 23 | + - Notable properties: |
| 24 | + - `<IsTestProject>true</IsTestProject>` and `<IsPackable>false</IsPackable>` in tests. |
| 25 | + - `<Nullable>disable</Nullable>` in tests (be mindful when adding nullable-sensitive code in tests). |
| 26 | + - `<NoWarn>xUnit1033;CS8002</NoWarn>` to quiet specific analyzer warnings. |
| 27 | + - Test logs: `VSTestLogger` and `VSTestResultsDirectory` are preconfigured to write TRX per TFM into `test-results/<TFM>`. |
| 28 | + |
| 29 | +- Packaging (FYI) |
| 30 | + - CI workflow `.github/workflows/build-dev.yml` demonstrates release packaging: `dotnet pack -c Release -o nuget -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg` and `dotnet nuget push` to nuget.org using OIDC via `NuGet/login@v1`. |
| 31 | + |
| 32 | +--- |
| 33 | + |
| 34 | +### Testing |
| 35 | + |
| 36 | +- Test frameworks and helpers |
| 37 | + - xUnit is the test framework. `test/Directory.Build.props` adds global `using` aliases for `Xunit`, `FluentAssertions`, and `AutoFixture` so you can use `[Fact]`, `Should()`, etc., without explicit `using` statements in each test file. |
| 38 | + - Additional packages commonly used in unit tests (see `test/RestSharp.Tests/RestSharp.Tests.csproj`): `Moq`, `RichardSzalay.MockHttp`, `System.Net.Http.Json`. |
| 39 | + - Integrated tests leverage `WireMockServer` (see `RestSharp.Tests.Integrated`) and use assets under `Assets/` where needed. |
| 40 | + |
| 41 | +- Running tests |
| 42 | + - Run all tests for the entire solution: |
| 43 | + ``` |
| 44 | + dotnet test RestSharp.sln -c Debug |
| 45 | + ``` |
| 46 | + - Run a specific test project (multi-targeted will run for all installed TFMs): |
| 47 | + ``` |
| 48 | + dotnet test test/RestSharp.Tests/RestSharp.Tests.csproj |
| 49 | + ``` |
| 50 | + - Select a single target framework (useful if you don’t have all SDKs installed): |
| 51 | + ``` |
| 52 | + dotnet test test/RestSharp.Tests/RestSharp.Tests.csproj -f net8.0 |
| 53 | + ``` |
| 54 | + - Run by fully-qualified name (FQN) — recommended for pinpointing a single test: |
| 55 | + ``` |
| 56 | + dotnet test test/RestSharp.Tests/RestSharp.Tests.csproj \ |
| 57 | + --filter "FullyQualifiedName=RestSharp.Tests.UrlBuilderTests_Get.Should_build_url_with_query" |
| 58 | + ``` |
| 59 | + Notes: |
| 60 | + - Prefer `FullyQualifiedName` for precision. Class and method names are case-sensitive. |
| 61 | + - You can combine with `-f net8.0` to avoid cross-TFM failures when only one SDK is present. |
| 62 | + - Run by namespace or class: |
| 63 | + ``` |
| 64 | + dotnet test test/RestSharp.Tests/RestSharp.Tests.csproj --filter "RestSharp.Tests.UrlBuilderTests" |
| 65 | + ``` |
| 66 | +
|
| 67 | +- Logs and results |
| 68 | + - TRX logs are written per TFM into `test-results/<TFM>/` with file name `<ProjectName>.trx` as configured by `VSTestLogger`/`VSTestResultsDirectory` in `Directory.Build.props`. |
| 69 | + - To additionally emit console diagnostics: |
| 70 | + ``` |
| 71 | + dotnet test -v n |
| 72 | + ``` |
| 73 | +
|
| 74 | +- Code coverage |
| 75 | + - The `coverlet.collector` package is referenced for data-collector based coverage. |
| 76 | + - Example coverage run (generates cobertura xml): |
| 77 | + ``` |
| 78 | + dotnet test test/RestSharp.Tests/RestSharp.Tests.csproj \ |
| 79 | + -f net8.0 \ |
| 80 | + --collect:"XPlat Code Coverage" \ |
| 81 | + -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura |
| 82 | + ``` |
| 83 | + - Output will be placed under the test results directory for the given run. |
| 84 | +
|
| 85 | +- Adding new tests |
| 86 | + - New xUnit test files can be added anywhere under the corresponding test project directory; no extra `using` directives are required for `Xunit`/`FluentAssertions`/`AutoFixture` thanks to `Directory.Build.props` implicit usings. |
| 87 | + - Prefer co-locating tests by feature area and splitting large suites using partial classes (see `UrlBuilderTests.cs` with `UrlBuilderTests.Get.cs`/`Post.cs` linked via `DependentUpon` in the project) to keep navigation manageable. |
| 88 | + - For HTTP behavior, use `WireMockServer` in integrated tests rather than live endpoints. See `test/RestSharp.Tests.Integrated/DownloadFileTests.cs` for a pattern: spin up a server, register expectations in the constructor, and dispose in `IDisposable.Dispose`. |
| 89 | + - Follow existing assertions style with FluentAssertions. |
| 90 | +
|
| 91 | +- Verified example run |
| 92 | + - The test infrastructure was validated by executing a trivial `[Fact]` via fully qualified name using the built-in test runner. Use the FQN filtering example above to replicate. |
| 93 | +
|
| 94 | +--- |
| 95 | +
|
| 96 | +### Additional development information |
| 97 | +
|
| 98 | +- Code style and analyzers |
| 99 | + - Adhere to the style used in `src/RestSharp` and existing tests. Test projects disable nullable by default; the main library might have different settings (check the respective `*.csproj` and imported props). |
| 100 | + - The repo uses central package management via `Directory.Packages.props`. Prefer bumping versions there unless a project has a specific override. |
| 101 | +
|
| 102 | +- HTTP/integration test guidance |
| 103 | + - Use `WireMockServer` for predictable, offline tests. Avoid time-sensitive or locale-sensitive assertions in integrated tests; when needed, pin formats (e.g., `"d"`) as seen in `ObjectParserTests`. |
| 104 | + - Be explicit about stream usage across TFMs. Some tests use `#if NET8_0_OR_GREATER` to select APIs like `Stream.ReadExactly`. |
| 105 | +
|
| 106 | +- Multi-TFM nuances |
| 107 | + - When debugging TFM-specific behavior, run `dotnet test -f <TFM>` to reproduce. Conditional compilation symbols (e.g., `NET8_0_OR_GREATER`) are used in tests; ensure your changes compile under all declared target frameworks or scope them with `#if`. |
| 108 | +
|
| 109 | +- Artifacts and outputs |
| 110 | + - NuGet packages are output to `nuget/` during local `dotnet pack` unless overridden. |
| 111 | + - Test artifacts are collected under `test-results/<TFM>/` per the configuration. |
| 112 | +
|
| 113 | +- Common pitfalls |
| 114 | + - Running tests targeting `net48` on non-Windows environments requires the reference assemblies (already pulled by package reference) but still may need Mono/compat setup on some systems; if unavailable, skip with `-f`. |
| 115 | + - Some integrated tests rely on asset files under `Assets/`. Ensure `AppDomain.CurrentDomain.BaseDirectory` resolves correctly when running from IDE vs CLI. |
| 116 | +
|
| 117 | +--- |
| 118 | +
|
| 119 | +### Quick commands reference |
| 120 | +
|
| 121 | +``` |
| 122 | +# Build solution |
| 123 | +dotnet build RestSharp.sln -c Release |
| 124 | + |
| 125 | +# Run all tests for a single TFM |
| 126 | +dotnet test test/RestSharp.Tests/RestSharp.Tests.csproj -f net8.0 |
| 127 | + |
| 128 | +# Run a single test by FQN |
| 129 | +dotnet test test/RestSharp.Tests/RestSharp.Tests.csproj --filter "FullyQualifiedName=RestSharp.Tests.ObjectParserTests.ShouldUseRequestProperty" |
| 130 | + |
| 131 | +# Pack (local) |
| 132 | +dotnet pack src/RestSharp/RestSharp.csproj -c Release -o nuget -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg |
| 133 | +``` |
0 commit comments