Merge pull request #191 from ViPro-Technologies/chore/cleanup

chore: server and test analyzer cleanup
main
VinPropane 2026-06-27 23:32:04 -04:00 committed by GitHub
commit 177b316efa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
230 changed files with 582 additions and 1018 deletions

View File

@ -50,31 +50,57 @@ if (string.IsNullOrEmpty(key))
return false;
```
- **Indentation:** **4 spaces** per level; no tabs unless the file already uses tabs—never mix.
- **Trailing whitespace:** do not leave spaces or tabs at the end of a line, including blank lines between statements (RCS1037).
- **`var`:** use when the type is obvious from the right-hand side; use explicit types when it improves readability or for literals where the type matters.
- **File-scoped namespaces** (`namespace X;`) for new single-namespace files when the SDK/version allows.
- **Empty marker types** (collection fixtures, `[CollectionDefinition]`, marker interfaces): omit `{ }` and end with `;` when the type has no members (RCS1251).
- **Pattern matching / nullability:** prefer modern C# features where they simplify code; honor **nullable reference type** annotations when the project enables them.
## Collection expressions (IDE0305)
## Collection expressions (IDE0300 / IDE0305)
- Prefer **`["a", "b"]`** over **`new[] { "a", "b" }`** for inline string (and other) array/list literals.
- Prefer **collection spread** (`[.. source]`) over **`.ToArray()`** / **`.ToList()`** when materializing a sequence into a new array or list for return values, record `with` copies, or local snapshots.
- Give an **explicit target type** when the compiler cannot infer one (CS9176), e.g. `string[] ids = [.. query.Select(static x => x.Id)];`.
- In **assertions**, avoid passing a bare spread directly to APIs with span overloads (e.g. `Assert.Equal`) — assign to a typed local first:
- In **assertions**, avoid passing a bare spread directly to APIs with span overloads (e.g. `Assert.Equal`) — assign to a typed local first, or use a **`private static readonly`** field when the same literal is reused (CA1861):
```csharp
// Prefer
return [.. query];
GrantedItems = [.. row.GrantedItems],
new SkillDefRow("salvage", "gather", "Salvage", ["activity", "mission_reward"]),
// When type inference fails
string[] expectedOrder = [.. registry.GetDefinitionsInIdOrder().Select(static d => d.Id)];
string[] actualOrder = [.. body.Quests.Select(static row => row.QuestId)];
Assert.Equal(expectedOrder, actualOrder);
// Reused expected literals in tests
private static readonly string[] ExpectedSkillIds = ["intrusion", "refine", "salvage"];
Assert.Equal(ExpectedSkillIds, ids);
// Avoid (ambiguous Assert overloads; unnecessary allocation helper)
Assert.Equal(expectedOrder, [.. body.Quests.Select(static row => row.QuestId)]);
return query.ToArray();
new[] { "activity", "mission_reward" }
```
## Target-typed `new` (IDE0090)
- When the return type or variable type is already explicit, prefer **`new()`** over repeating the type name in object initializers (common in test request helpers):
```csharp
private static SkillProgressionGrantRequest Grant(...) =>
new()
{
SchemaVersion = schemaVersion,
SkillId = skillId,
};
```
## Async pass-through (CDT1003)
- Do not mark a method **`async`** when it only **`await`**s and returns a single **`Task`** — return that task directly with an expression body or **`return`** statement.
## `using` / `await using` (IDE0063)
- When a **`using` or `await using` block contains exactly one statement**, prefer the declaration form without braces: `await using var conn = …;` then the single statement on following lines **only if** it is still logically one resource scope (typical for `NpgsqlConnection` + one command in integration-test reset helpers).
@ -83,15 +109,19 @@ return query.ToArray();
## Local `const` (RCS1118)
- When a local is initialized from a **compile-time constant** (string literal, numeric literal, or `public const` field), declare it **`const`** instead of **`var`**.
- When a local is initialized from a **compile-time constant** (string literal, raw string literal, numeric literal, or `public const` field), declare it **`const`** instead of **`var`**.
```csharp
const string questId = PrototypeE7M1QuestCatalogRules.GatherIntroQuestId;
const string fixtureJson = """
{ "schemaVersion": 1 }
""";
```
## Inline declarations (IDE0018)
## Inline declarations (IDE0018 / IDE0059)
- Prefer **inline initialization** over declare-then-assign when the analyzer suggests it, e.g. `var outcome = Operation(...)` and `TryGet(..., out var snapshot)` instead of separate upfront declarations.
- Do **not** pre-initialize locals with **`default`**, **`null`**, or **`false`** when the variable is assigned in the next block before its first read (IDE0059) — declare without an initializer instead.
```csharp
// Prefer — single disposable, single follow-on statement
@ -119,8 +149,27 @@ var store = secondScope.ServiceProvider.GetRequiredService<IExampleStore>(); //
## Concrete return types (CA1859)
- When a private helper always returns a materialized array, prefer the **concrete array type** as the return type (e.g. `RewardItemGrantApplied[]`) instead of `IReadOnlyList<T>` if callers only need the array and analyzers suggest it.
- When a private helper always returns a materialized array or list, prefer the **concrete type** as the return type (e.g. `List<T>`, `T[]`, `Dictionary<,>`) instead of `IReadOnlyList<T>` / `IReadOnlyDictionary<,>` when callers only need the materialized value and analyzers suggest it.
- Same rule applies to **`BuildDefinitionsInIdOrder`**, **`MapSlots`**, **`ReadBindings`**, and similar helpers that always construct a new collection.
## Logging guards (CA1873)
- Before **`LogInformation`**, **`LogDebug`**, or other structured logs whose arguments allocate (interpolated strings, exceptions, collection counts), guard with **`logger.IsEnabled(LogLevel.…)`** (or **`logger?.IsEnabled(...) is true`** when the logger is nullable).
```csharp
if (logger.IsEnabled(LogLevel.Information))
{
logger.LogInformation("Loaded catalog from {Path} with {Count} rows.", path, rows.Count);
}
```
## SQL parameter names (RCS1015)
- When an ADO.NET / Npgsql parameter name matches a local variable, prefer **`nameof(variable)`** over a string literal: **`AddWithValue(nameof(xp), xp)`**.
## Arithmetic clarity (RCS1123)
- In mixed products inside calls (e.g. **`Math.Sqrt((dx * dx) + (dz * dz))`**), parenthesize each product so precedence is explicit.
- Prefer **expression-bodied** members only when they stay one clear idea.
- **LINQ:** favor readability over micro-chains; break complex queries across lines.
@ -133,7 +182,14 @@ var store = secondScope.ServiceProvider.GetRequiredService<IExampleStore>(); //
## Documentation
- Use **`///` XML doc comments** on public APIs (types and members) when behavior or contracts are not obvious.
- **Primary-constructor records:** include a **`<summary>`** on the type. Prefer **`<see cref="PropertyName"/>`** in the summary for positional parameters. Do **not** use **`<param>`** on **`record struct`** primary constructors — Roslynator reports false-positive **RCS1263** ([roslynator#1730](https://github.com/dotnet/roslynator/issues/1730)). **`record class`** / **`class`** primary constructors may use `<param>` when the analyzer accepts them.
- **Primary-constructor records:** include a **`<summary>`** on the type. Document positional parameters with **`<see cref="PropertyName"/>`** inside the summary — **never** **`/// <param>`** on **`record struct`** or **`record class`** primary constructors (Roslynator **RCS1263** false positive; [roslynator#1730](https://github.com/dotnet/roslynator/issues/1730)).
- **Property / field docs:** every **`///`** block must include a **`<summary>`** — do not ship **`<remarks>`**-only comments (RCS1139). Put extra detail in **`<remarks>`** after the summary when needed.
```csharp
/// <summary>Deny reason when <see cref="Granted"/> is <c>false</c>.</summary>
/// <remarks>Stable snake_case values; see README.</remarks>
public string? ReasonCode { get; init; }
```
## Null checks (IDE0270)
@ -207,3 +263,4 @@ public async Task PostExample_ShouldReturnOk_WhenBodyValid()
## Tooling
- Prefer fixes that satisfy built-in **.NET analyzers** / `dotnet format` (if adopted) rather than fighting IDE warnings without reason.
- Remove **unnecessary `using` directives** (IDE0005 / CS8019) — with **implicit usings** and **global usings**, many `Microsoft.Extensions.*`, `System.Threading`, and `System.Linq` imports are redundant. Run `dotnet format <project>.csproj --diagnostics IDE0005 --severity info` before merge on touched projects.

View File

@ -0,0 +1,57 @@
# Code review — chore/cleanup analyzer pass
**Date:** 2026-06-27
**Scope:** Branch `chore/cleanup` — commit `b233fa0` vs `2cf8bcd` (merge base on `main`)
**Base:** `2cf8bcd` (merge of PR #190)
**Follow-up:** Suggestions and nits below are **done** (strikethrough + **Done.**).
## Verdict
**Approve with nits**
## Summary
This is a broad mechanical refactor across `NeonSprawl.Server` and `NeonSprawl.Server.Tests` (231 files, net 524 lines): collection expressions, primary-constructor catalog types, concrete private helper return types (CA1859), logging `IsEnabled` guards (CA1873), record XML doc fixes (RCS1263/RCS1139), `nameof` for SQL parameters, quest-store mutator delegate → `Func` + `MutateRowResult` record struct, removal of redundant `using` directives via new `GlobalUsings.cs`, and a substantial `csharp-style.md` appendix documenting the patterns. No HTTP routes, request bodies, or game contracts change. Build is clean (0 warnings). Full `dotnet test` passed **905/906** locally with one intermittent Postgres integration failure under parallel load; the same Postgres specs pass in isolation on this branch and on the parent commit.
## Documentation checked
| Path | Result |
|------|--------|
| `docs/plans/` (NEO-* / E7M4 stories) | **N/A** — unticketed `chore:` branch; no feature acceptance criteria |
| `.cursor/rules/csharp-style.md` | **Matches** — new sections document patterns applied in this diff (collection expressions, CA1859/CA1873, RCS1015, record XML docs, test GlobalUsings) |
| `docs/decomposition/modules/module_dependency_register.md` | **N/A** — no module behavior or authority changes |
| `docs/decomposition/modules/documentation_and_implementation_alignment.md` | **N/A** — no implementation-status update required |
| `bruno/neon-sprawl-server/collection.bru` | **Matches**~~Partially matches~~ docs block removed (**Done.**) |
## Blocking issues
None.
## Suggestions
1. ~~**Remove the Bruno `docs { }` block** in `bruno/neon-sprawl-server/collection.bru`. The note (“chore/cleanup analyzer pass: no HTTP route or request-body changes”) belongs in the PR/commit message, not in the Bruno collection metadata consumers may read as API documentation.~~ **Done.** Removed the `docs { }` block from `collection.bru`.
2. ~~**Preserve explicit `StringComparer.Ordinal` in quest objective counter copies.** In `PostgresPlayerQuestStateStore.MutateObjectiveCounter`, the old code used `new Dictionary<string, int>(row.ObjectiveCounters, StringComparer.Ordinal)`. The new `ToDictionary` call relies on default string equality (ordinal in practice). For consistency with the rest of the quests module and defense-in-depth, pass `StringComparer.Ordinal` to `ToDictionary` or keep the dictionary copy constructor.~~ **Done.** `ToDictionary(..., StringComparer.Ordinal)` in `PostgresPlayerQuestStateStore.cs`.
3. ~~**Confirm Postgres integration stability under parallel xUnit.** Full-suite runs intermittently fail one of `FactionStandingPersistenceIntegrationTests`, `GigProgressionGrantPersistenceIntegrationTests`, or `SkillProgressionGrantPersistenceIntegrationTests` (expected persisted value vs `0`), while filtered runs pass on both `2cf8bcd` and `b233fa0`. This looks like pre-existing collection/fixture contention rather than a logic regression from this diff, but worth a quick check that `[Collection("Postgres integration")]` isolation is sufficient before merge if CI runs the full suite in parallel.~~ **Done.** Root cause for gig flake: `GigProgressionGrantPersistenceIntegrationTests` used wall-clock `Task.Delay` while cooldown uses `TimeProvider`; casts could return HTTP 200 with `on_cooldown` (`Accepted: false`) without defeat. Fixed by registering `FakeTimeProvider` on `PostgresWebApplicationFactory` and advancing the fake clock in the gig persistence test (same pattern as `InMemoryWebApplicationFactory`). Full suite **906/906** after fix.
## Nits
- ~~Nit: `GlobalUsings.cs` pulls in domain namespaces (`NeonSprawl.Server.Game.Npc`, `NeonSprawl.Server.Tests.Game.Npc`, etc.). Works today (0 build warnings), but a one-line file comment listing intentional globals would help future contributors avoid accidental name clashes.~~ **Done.** File header comment added.
- ~~Nit: `QuestProgressIds.cs` has a whitespace-only trailing blank line before the closing brace — harmless; could drop in a follow-up.~~ **Done.**
- Nit: `QuestStateOperations.DenyAccept` no longer threads `playerId` / `questId`; telemetry comment correctly says “capture at call site when wiring E9.M1.” Fine for now — just remember at E9.M1.
- Nit: `NpcRuntimeOperations.AdvanceAll` drops the postidle→aggro `TryGet` refresh; the while-loop `TryGet` on the first iteration makes this equivalent. No action needed.
- Nit: `PostgresPositionStateStore` drops unused `IOptions<GamePositionOptions>` / startup validation — correct dead-code removal; DI registration unchanged.
## Verification
```bash
cd server/NeonSprawl.Server && dotnet build
cd server/NeonSprawl.Server.Tests && dotnet test
cd server/NeonSprawl.Server.Tests && dotnet test --filter "FullyQualifiedName~PersistenceIntegrationTests"
```
Expect **906** passed; if a single Postgres persistence test fails under full parallel run, re-run filtered as above to distinguish flake from regression.
Manual Godot QA: none (no client or player-visible surface changes).

View File

@ -1,17 +1,10 @@
using System.Net;
using System.Net.Http.Json;
using System.Text;
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.AbilityInput;
using NeonSprawl.Server.Game.Combat;
using NeonSprawl.Server.Game.Encounters;
using NeonSprawl.Server.Game.Gigs;
using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.Skills;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Game.Targeting;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.AbilityInput;
@ -36,8 +29,8 @@ public sealed class AbilityCastApiTests
post.EnsureSuccessStatusCode();
}
private static async Task LockPrototypeTargetAlphaAsync(HttpClient client) =>
await LockPrototypeTargetAsync(client, PrototypeNpcRegistry.PrototypeNpcMeleeId);
private static Task LockPrototypeTargetAlphaAsync(HttpClient client) =>
LockPrototypeTargetAsync(client, PrototypeNpcRegistry.PrototypeNpcMeleeId);
private static async Task LockPrototypeTargetAsync(HttpClient client, string targetId)
{

View File

@ -1,10 +1,5 @@
using System.Net;
using System.Net.Http.Json;
using NeonSprawl.Server.Game.AbilityInput;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Game.Targeting;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.AbilityInput;

View File

@ -1,8 +1,4 @@
using System.Net;
using System.Net.Http.Json;
using System.Text;
using NeonSprawl.Server.Game.AbilityInput;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.AbilityInput;

View File

@ -1,9 +1,5 @@
using System.Net;
using System.Net.Http.Json;
using NeonSprawl.Server.Game.AbilityInput;
using NeonSprawl.Server.Tests.Game.PositionState;
using Npgsql;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.AbilityInput;

View File

@ -1,5 +1,4 @@
using NeonSprawl.Server.Game.AbilityInput;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.AbilityInput;

View File

@ -1,12 +1,6 @@
using System.Net;
using System.Text;
using System.Text.Json.Nodes;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using NeonSprawl.Server.Game.Combat;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Combat;

View File

@ -1,10 +1,5 @@
using System.IO;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using NeonSprawl.Server.Game.AbilityInput;
using NeonSprawl.Server.Game.Combat;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Combat;

View File

@ -1,8 +1,4 @@
using System.Linq;
using System.Net;
using System.Net.Http.Json;
using NeonSprawl.Server.Game.Combat;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Combat;

View File

@ -1,9 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Combat;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Tests;
using NeonSprawl.Server.Tests.Game.Npc;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Combat;

View File

@ -1,10 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.AbilityInput;
using NeonSprawl.Server.Game.Combat;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Tests;
using NeonSprawl.Server.Tests.Game.Npc;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Combat;

View File

@ -1,13 +1,7 @@
using System.Net;
using System.Net.Http.Json;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.AbilityInput;
using NeonSprawl.Server.Game.Combat;
using NeonSprawl.Server.Game.Encounters;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Combat;

View File

@ -1,13 +1,6 @@
using System.Linq;
using System.Net;
using System.Net.Http.Json;
using NeonSprawl.Server.Game.AbilityInput;
using NeonSprawl.Server.Game.Combat;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Game.Targeting;
using NeonSprawl.Server.Tests;
using NeonSprawl.Server.Tests.Game.Npc;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Combat;

View File

@ -1,10 +1,6 @@
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.AbilityInput;
using NeonSprawl.Server.Game.Combat;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Tests.Game.Npc;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Combat;

View File

@ -1,13 +1,7 @@
using System.Net;
using System.Net.Http.Json;
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.AbilityInput;
using NeonSprawl.Server.Game.Combat;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.Targeting;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Combat;

View File

@ -1,7 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Combat;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Combat;

View File

@ -1,4 +1,3 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Contracts;
using NeonSprawl.Server.Game.Encounters;
using NeonSprawl.Server.Game.Factions;
@ -6,9 +5,6 @@ using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Game.Quests;
using NeonSprawl.Server.Game.Rewards;
using NeonSprawl.Server.Game.Skills;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Contracts;

View File

@ -1,12 +1,8 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Contracts;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Game.Rewards;
using NeonSprawl.Server.Game.Skills;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Contracts;

View File

@ -1,8 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Contracts;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Contracts;

View File

@ -1,11 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.Contracts;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.Quests;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Contracts;

View File

@ -1,11 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.Contracts;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Tests.Game.PositionState;
using Npgsql;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Contracts;

View File

@ -1,10 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.Contracts;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Tests.Game.PositionState;
using Npgsql;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Contracts;

View File

@ -1,11 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.Contracts;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.Rewards;
using NeonSprawl.Server.Tests.Game.PositionState;
using Npgsql;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Contracts;

View File

@ -1,13 +1,8 @@
using System.Collections.Frozen;
using System.Text;
using Microsoft.Extensions.Logging.Abstractions;
using NeonSprawl.Server.Game.Contracts;
using NeonSprawl.Server.Game.Encounters;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.Quests;
using NeonSprawl.Server.Game.Skills;
using NeonSprawl.Server.Tests.Game.Skills;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Contracts;

View File

@ -1,14 +1,4 @@
using System.Collections.Frozen;
using System.Text;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using NeonSprawl.Server.Game.Contracts;
using NeonSprawl.Server.Game.Encounters;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.Skills;
using NeonSprawl.Server.Tests;
using NeonSprawl.Server.Tests.Game.Skills;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Contracts;

View File

@ -1,9 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.Contracts;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Contracts;

View File

@ -1,8 +1,6 @@
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.Contracts;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.Rewards;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Contracts;

View File

@ -1,13 +1,9 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.Crafting;
using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Game.Quests;
using NeonSprawl.Server.Game.Rewards;
using NeonSprawl.Server.Game.Skills;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Crafting;

View File

@ -1,12 +1,6 @@
using System.Net;
using System.Net.Http.Json;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Crafting;
using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Game.Skills;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Crafting;

View File

@ -1,14 +1,8 @@
using System.Collections.Frozen;
using System.Net;
using System.Text;
using System.Text.Json.Nodes;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using NeonSprawl.Server.Game.Crafting;
using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Crafting;

View File

@ -1,11 +1,6 @@
using System.Collections.Frozen;
using System.IO;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using NeonSprawl.Server.Game.Crafting;
using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Crafting;

View File

@ -1,8 +1,4 @@
using System.Linq;
using System.Net;
using System.Net.Http.Json;
using NeonSprawl.Server.Game.Crafting;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Crafting;

View File

@ -1,4 +1,3 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Contracts;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.Encounters;
@ -6,9 +5,6 @@ using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Game.Quests;
using NeonSprawl.Server.Game.Rewards;
using NeonSprawl.Server.Game.Skills;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Encounters;

View File

@ -1,4 +1,3 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Contracts;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.Encounters;
@ -6,9 +5,6 @@ using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Game.Quests;
using NeonSprawl.Server.Game.Rewards;
using NeonSprawl.Server.Game.Skills;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Encounters;

View File

@ -1,11 +1,5 @@
using System.Net;
using System.Text;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using NeonSprawl.Server.Game.Encounters;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Encounters;

View File

@ -1,7 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Encounters;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Encounters;

View File

@ -1,7 +1,4 @@
using System.Net;
using System.Net.Http.Json;
using NeonSprawl.Server.Game.Encounters;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Encounters;

View File

@ -1,13 +1,7 @@
using System.Net;
using System.Net.Http.Json;
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.AbilityInput;
using NeonSprawl.Server.Game.Encounters;
using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.Targeting;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Encounters;

View File

@ -1,6 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Encounters;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Encounters;

View File

@ -1,5 +1,4 @@
using NeonSprawl.Server.Game.Encounters;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Encounters;

View File

@ -1,5 +1,4 @@
using NeonSprawl.Server.Game.Encounters;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Encounters;

View File

@ -1,5 +1,4 @@
using NeonSprawl.Server.Game.Encounters;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Encounters;

View File

@ -1,8 +1,4 @@
using System.Text;
using System.Text.Json.Nodes;
using Microsoft.Extensions.Logging.Abstractions;
using NeonSprawl.Server.Game.Encounters;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Encounters;

View File

@ -1,7 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Encounters;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Encounters;

View File

@ -1,7 +1,4 @@
using System.Text;
using Microsoft.Extensions.Logging.Abstractions;
using NeonSprawl.Server.Game.Factions;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Factions;
@ -90,7 +87,7 @@ public class FactionDefinitionCatalogLoaderTests
{
// Arrange
var (_, factionsDir, schemaPath) = CreateTempContentLayout();
var singleFaction = """
const string singleFaction = """
{
"schemaVersion": 1,
"factions": [
@ -118,7 +115,7 @@ public class FactionDefinitionCatalogLoaderTests
{
// Arrange
var (_, factionsDir, schemaPath) = CreateTempContentLayout();
var oneFaction = """
const string oneFaction = """
{
"schemaVersion": 1,
"factions": [

View File

@ -1,9 +1,4 @@
using System.Text;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Factions;

View File

@ -1,9 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.Quests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Factions;

View File

@ -1,14 +1,8 @@
using System.Linq;
using System.Net;
using System.Net.Http.Json;
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Game.Quests;
using NeonSprawl.Server.Game.Rewards;
using NeonSprawl.Server.Game.Skills;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Factions;

View File

@ -1,10 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Tests.Game.PositionState;
using Npgsql;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Factions;

View File

@ -1,8 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.PositionState;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Factions;

View File

@ -1,5 +1,4 @@
using NeonSprawl.Server.Game.Factions;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Factions;

View File

@ -1,10 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Tests.Game.PositionState;
using Npgsql;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Factions;

View File

@ -1,9 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Factions;

View File

@ -1,13 +1,9 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.Gathering;
using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Game.Quests;
using NeonSprawl.Server.Game.Rewards;
using NeonSprawl.Server.Game.Skills;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Gathering;

View File

@ -1,5 +1,4 @@
using NeonSprawl.Server.Game.Gathering;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Gathering;

View File

@ -1,12 +1,6 @@
using System.Text;
using System.Text.Json.Nodes;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using NeonSprawl.Server.Game.Gathering;
using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Gathering;

View File

@ -1,9 +1,4 @@
using System.IO;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using NeonSprawl.Server.Game.Gathering;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Gathering;

View File

@ -1,8 +1,4 @@
using System.Linq;
using System.Net;
using System.Net.Http.Json;
using NeonSprawl.Server.Game.Gathering;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Gathering;

View File

@ -1,10 +1,5 @@
using System.Net;
using System.Net.Http.Json;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Gathering;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Gathering;

View File

@ -1,7 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Gathering;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Gathering;

View File

@ -1,8 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Gathering;
using NeonSprawl.Server.Tests.Game.PositionState;
using Npgsql;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Gathering;

View File

@ -1,7 +1,5 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Gigs;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Gigs;

View File

@ -1,15 +1,8 @@
using System.Linq;
using System.Net.Http.Json;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.AbilityInput;
using NeonSprawl.Server.Game.Gigs;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.Targeting;
using NeonSprawl.Server.Tests.Game.PositionState;
using Npgsql;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Gigs;
@ -31,7 +24,10 @@ public sealed class GigProgressionGrantPersistenceIntegrationTests(PostgresInteg
TargetId = PrototypeNpcRegistry.PrototypeNpcMeleeId,
};
// Act — defeat alpha through first host (four pulses)
// Act — defeat alpha through first host (pulse loop; fake clock avoids wall-clock cooldown flakes)
Assert.NotNull(Factory.FakeClock);
var clock = Factory.FakeClock;
clock.Advance(TimeSpan.FromSeconds(3) + TimeSpan.FromMilliseconds(50));
using (var firstClient = Factory.CreateClient())
{
await firstClient.PostAsJsonAsync(
@ -48,15 +44,26 @@ public sealed class GigProgressionGrantPersistenceIntegrationTests(PostgresInteg
SchemaVersion = TargetSelectRequest.CurrentSchemaVersion,
TargetId = PrototypeNpcRegistry.PrototypeNpcMeleeId,
});
for (var i = 0; i < 4; i++)
AbilityCastResponse? defeatBody = null;
for (var i = 0; i < 12; i++)
{
var response = await firstClient.PostAsJsonAsync("/game/players/dev-local-1/ability-cast", cast);
response.EnsureSuccessStatusCode();
if (i < 3)
var body = await response.Content.ReadFromJsonAsync<AbilityCastResponse>();
Assert.NotNull(body);
Assert.True(body!.Accepted, body.ReasonCode);
Assert.NotNull(body.CombatResolution);
if (body.CombatResolution!.TargetDefeated)
{
await Task.Delay(TimeSpan.FromSeconds(3.2));
defeatBody = body;
break;
}
clock.Advance(TimeSpan.FromSeconds(3) + TimeSpan.FromMilliseconds(50));
}
Assert.NotNull(defeatBody);
Assert.True(defeatBody!.CombatResolution!.TargetDefeated);
}
await using var secondFactory = new PostgresWebApplicationFactory();

View File

@ -1,8 +1,4 @@
using System.Linq;
using System.Net;
using System.Net.Http.Json;
using NeonSprawl.Server.Game.Gigs;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Gigs;

View File

@ -1,5 +1,4 @@
using NeonSprawl.Server.Game.World;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Interaction;
@ -62,10 +61,10 @@ public class HorizontalReachTests
public void IsWithinHorizontalRadius_NegativeRadius_ThrowsArgumentOutOfRange()
{
// Arrange
Action act = () => HorizontalReach.IsWithinHorizontalRadius(0, 0, 0, 0, -1.0);
// Act
var ex = Assert.Throws<ArgumentOutOfRangeException>(act);
var ex = Assert.Throws<ArgumentOutOfRangeException>(
() => HorizontalReach.IsWithinHorizontalRadius(0, 0, 0, 0, -1.0));
// Assert
Assert.NotNull(ex);

View File

@ -1,8 +1,4 @@
using System.Linq;
using System.Net;
using System.Net.Http.Json;
using NeonSprawl.Server.Game.Interaction;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Interaction;
@ -28,7 +24,8 @@ public class InteractablesWorldApiTests
Assert.Equal(5, body.Interactables.Count);
var ids = body.Interactables.Select(static x => x.InteractableId).ToList();
Assert.Equal(ids.OrderBy(static x => x, StringComparer.Ordinal).ToList(), ids);
string[] expectedOrder = [.. ids.OrderBy(static x => x, StringComparer.Ordinal)];
Assert.Equal(expectedOrder, ids);
var alpha = body.Interactables.Single(x => x.InteractableId == PrototypeInteractableRegistry.PrototypeResourceNodeAlphaId);
Assert.Equal("resource_node", alpha.Kind);

View File

@ -1,9 +1,5 @@
using System.Net;
using System.Net.Http.Json;
using System.Text;
using NeonSprawl.Server.Game.Interaction;
using NeonSprawl.Server.Game.PositionState;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Interaction;

View File

@ -1,13 +1,7 @@
using System.Linq;
using System.Net;
using System.Net.Http.Json;
using NeonSprawl.Server.Game.Gathering;
using NeonSprawl.Server.Game.Interaction;
using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.Skills;
using NeonSprawl.Server.Game.World;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Interaction;

View File

@ -1,11 +1,5 @@
using System.Linq;
using System.Net;
using System.Net.Http.Json;
using NeonSprawl.Server.Game.Interaction;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.Skills;
using NeonSprawl.Server.Game.World;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Interaction;

View File

@ -2,7 +2,6 @@ using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Time.Testing;
using NeonSprawl.Server.Game.AbilityInput;
@ -12,11 +11,8 @@ using NeonSprawl.Server.Game.Factions;
using NeonSprawl.Server.Game.Gathering;
using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.Quests;
using NeonSprawl.Server.Game.Skills;
using Npgsql;
namespace NeonSprawl.Server.Tests.Game.Interaction;
@ -110,19 +106,19 @@ internal sealed class SalvageActivityDeniedSkillRegistry : ISkillDefinitionRegis
"salvage",
"gather",
"Salvage",
new[] { "mission_reward" });
["mission_reward"]);
private static readonly SkillDefRow Refine = new(
"refine",
"process",
"Refine",
new[] { "activity", "mission_reward", "trainer" });
["activity", "mission_reward", "trainer"]);
private static readonly SkillDefRow Intrusion = new(
"intrusion",
"tech",
"Intrusion",
new[] { "activity", "mission_reward", "book_or_item" });
["activity", "mission_reward", "book_or_item"]);
private static readonly IReadOnlyList<SkillDefRow> Ordered =
[

View File

@ -1,6 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Items;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Items;

View File

@ -1,12 +1,6 @@
using System.Net;
using System.Text;
using System.Text.Json.Nodes;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Items;

View File

@ -1,9 +1,4 @@
using System.IO;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Items;

View File

@ -1,8 +1,4 @@
using System.Linq;
using System.Net;
using System.Net.Http.Json;
using NeonSprawl.Server.Game.Items;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Items;

View File

@ -1,8 +1,4 @@
using System.Linq;
using System.Net;
using System.Net.Http.Json;
using NeonSprawl.Server.Game.Items;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Items;

View File

@ -1,6 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Items;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Items;

View File

@ -1,10 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.Items;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Tests.Game.PositionState;
using Npgsql;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Items;

View File

@ -1,11 +1,6 @@
using System.Collections.Frozen;
using System.Net;
using System.Text;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.Logging.Abstractions;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Tests.Game.Skills;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Mastery;

View File

@ -1,8 +1,4 @@
using System.Net;
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Mastery;

View File

@ -1,12 +1,5 @@
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Game.Skills;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Mastery;
@ -18,7 +11,7 @@ public sealed class MasteryFixtureApiTests
private static MasteryFixtureRequest ValidFixture(
bool resetPerkState = true,
Dictionary<string, int>? skillXp = null) =>
new MasteryFixtureRequest
new()
{
SchemaVersion = MasteryFixtureRequest.CurrentSchemaVersion,
ResetPerkState = resetPerkState,

View File

@ -1,12 +1,4 @@
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Text;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Game.Skills;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Mastery;
@ -19,7 +11,7 @@ public sealed class PerkStateApiTests
int tierIndex,
string branchId,
int schemaVersion = PerkBranchSelectRequest.CurrentSchemaVersion) =>
new PerkBranchSelectRequest
new()
{
SchemaVersion = schemaVersion,
SkillId = skillId,
@ -28,7 +20,7 @@ public sealed class PerkStateApiTests
};
private static SkillProgressionGrantRequest SalvageGrant(int amount) =>
new SkillProgressionGrantRequest
new()
{
SchemaVersion = SkillProgressionGrantRequest.CurrentSchemaVersion,
SkillId = "salvage",

View File

@ -1,11 +1,6 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.Skills;
using NeonSprawl.Server.Tests.Game.PositionState;
using Npgsql;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Mastery;

View File

@ -1,11 +1,6 @@
using System.Net.Http.Json;
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Interaction;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.Skills;
using NeonSprawl.Server.Game.World;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Mastery;

View File

@ -1,7 +1,4 @@
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Game.PositionState;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Npc;

View File

@ -1,11 +1,6 @@
using System.Net.Http.Json;
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.AbilityInput;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.Targeting;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Npc;

View File

@ -1,5 +1,3 @@
using NeonSprawl.Server.Game.Npc;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Npc;

View File

@ -1,7 +1,3 @@
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Game.PositionState;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Npc;

View File

@ -1,4 +1,3 @@
using NeonSprawl.Server.Game.Npc;
namespace NeonSprawl.Server.Tests.Game.Npc;

View File

@ -1,12 +1,5 @@
using System.Net;
using System.Text;
using System.Text.Json.Nodes;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Npc;

View File

@ -1,10 +1,4 @@
using System.IO;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using NeonSprawl.Server.Game.Combat;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Npc;

View File

@ -1,8 +1,3 @@
using System.Linq;
using System.Net;
using System.Net.Http.Json;
using NeonSprawl.Server.Game.Npc;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Npc;

View File

@ -1,8 +1,5 @@
using Microsoft.Extensions.Options;
using NeonSprawl.Server.Game.Combat;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Game.PositionState;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Npc;

View File

@ -1,11 +1,5 @@
using System.Linq;
using System.Net;
using System.Net.Http.Json;
using NeonSprawl.Server.Game.AbilityInput;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Game.Targeting;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Npc;

View File

@ -1,7 +1,3 @@
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Npc;
@ -95,11 +91,11 @@ public class PrototypeNpcRegistryTests
.ToList();
// Assert
Assert.Equal(InstancesInIdOrder.Length, resolved.Count);
foreach (var row in resolved)
foreach (var (_, found, behaviorDefId, resolvedDef, resolvedId) in resolved)
{
Assert.True(row.Found);
Assert.True(row.Resolved);
Assert.Equal(row.BehaviorDefId, row.ResolvedId);
Assert.True(found);
Assert.True(resolvedDef);
Assert.Equal(behaviorDefId, resolvedId);
}
}
}

View File

@ -1,6 +1,5 @@
using NeonSprawl.Server.Game.AbilityInput;
using NeonSprawl.Server.Game.Combat;
using NeonSprawl.Server.Game.Npc;
namespace NeonSprawl.Server.Tests.Game.Npc;

View File

@ -1,14 +1,7 @@
using System.Net;
using System.Net.Http.Json;
using System.Text;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.AbilityInput;
using NeonSprawl.Server.Game.Npc;
using NeonSprawl.Server.Game.PositionState;
using NeonSprawl.Server.Game.Targeting;
using NeonSprawl.Server.Tests;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.PositionState;
@ -151,12 +144,8 @@ public class MoveCommandApiTests
// Arrange
await using var factory = new InMemoryWebApplicationFactory().WithWebHostBuilder(b =>
{
b.ConfigureTestServices(services =>
{
services.PostConfigure<GamePositionOptions>(o => o.MovementValidation.MaxVerticalStep = 0.5);
});
});
services.PostConfigure<GamePositionOptions>(o => o.MovementValidation.MaxVerticalStep = 0.5)));
var client = factory.CreateClient();
var cmd = new MoveCommandRequest
{

View File

@ -1,5 +1,4 @@
using NeonSprawl.Server.Game.PositionState;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.PositionState;

View File

@ -1,10 +1,5 @@
using System.Net;
using System.Net.Http.Json;
using System.Text;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using NeonSprawl.Server.Game.PositionState;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.PositionState;

View File

@ -1,7 +1,4 @@
using System.Net;
using System.Net.Http.Json;
using NeonSprawl.Server.Game.PositionState;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.PositionState;

Some files were not shown because too many files have changed in this diff Show More