Stufe 4c (#764): Bezeichner auf Englisch - Typen, Methoden, Felder, Parameter, Locals, Testnamen

Mit Roslyn umbenannt (Verweise folgen, Zeichenketten bleiben unberuehrt).
Nicht umbenannt, weil gespeichert oder ueber die API gebunden (Stufe 4e):
Properties, Record-Parameter, Enum-Member sowie die Parameter der
Endpunkt-Handler (Routen-/Query-Bindung ueber den Namen). Die JSON-Felder
anonymer Objekte bleiben ausdruecklich benannt (JsonFilter: pfad).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-10-04 13:18:43 +02:00
co-authored by Claude Opus 5.5
parent 837a634a22
commit 77062facc9
190 changed files with 4813 additions and 4813 deletions
@@ -11,10 +11,10 @@ namespace ClawdDotNet.Core.Tests.Budget;
/// no receipt, no indication on the task. In test operation all
/// weather data was therefore missing from 18:20 on, without it being visible outside the log.
/// </summary>
public sealed class BudgetsperreSichtbarTests
public sealed class BudgetBlockVisibleTests
{
/// <summary>Reports for every agent a daily consumption above every usual limit.</summary>
private sealed class ErschoepftesBudget : IUsageRepository
private sealed class ExhaustedBudget : IUsageRepository
{
public Task RecordAsync(RunUsage usage, CancellationToken ct) => Task.CompletedTask;
@@ -27,38 +27,38 @@ public sealed class BudgetsperreSichtbarTests
public Task<int> PurgeBeforeAsync(DateOnly date, CancellationToken ct) => Task.FromResult(0);
}
private static (EngineFixture Fixture, InMemoryAuditRepository Audit, AgentConfig Agent) Aufbau()
private static (EngineFixture Fixture, InMemoryAuditRepository Audit, AgentConfig Agent) Setup()
{
var audit = new InMemoryAuditRepository();
var fixture = new EngineFixture(audit, usage: new ErschoepftesBudget());
var fixture = new EngineFixture(audit, usage: new ExhaustedBudget());
var agent = fixture.AddAgent("wetterdienst");
agent.Budget.DailyCostUsd = 0.40m;
return (fixture, audit, agent);
}
[Fact]
public async Task Abgelehnter_frischer_Aufgabenlauf_hinterlaesst_einen_Beleg_an_der_Aufgabe()
public async Task Rejected_fresh_task_run_leaves_a_receipt_on_the_task()
{
var (fixture, audit, agent) = Aufbau();
var (fixture, audit, agent) = Setup();
var result = await fixture.Engine.RunAsync(
agent, "Hole die Warnungen", "inst", CancellationToken.None, source: "task", taskId: "t-unwetter");
result.Status.ShouldBe(AgentRunStatus.BudgetExceeded);
var beleg = audit.Receipts.ShouldHaveSingleItem();
beleg.TaskId.ShouldBe("t-unwetter");
beleg.AgentId.ShouldBe("wetterdienst");
beleg.Status.ShouldBe(nameof(AgentRunStatus.BudgetExceeded));
beleg.ResultRef.ShouldContain("Budget erschöpft");
beleg.ResultRef.ShouldContain("0,40", Case.Insensitive);
beleg.PromptTokens.ShouldBe(0);
beleg.CostUsd.ShouldBe(0m);
var receipt = audit.Receipts.ShouldHaveSingleItem();
receipt.TaskId.ShouldBe("t-unwetter");
receipt.AgentId.ShouldBe("wetterdienst");
receipt.Status.ShouldBe(nameof(AgentRunStatus.BudgetExceeded));
receipt.ResultRef.ShouldContain("Budget erschöpft");
receipt.ResultRef.ShouldContain("0,40", Case.Insensitive);
receipt.PromptTokens.ShouldBe(0);
receipt.CostUsd.ShouldBe(0m);
}
[Fact]
public async Task Abgelehnter_Lauf_im_Chatverlauf_hinterlaesst_ebenfalls_einen_Beleg()
public async Task Rejected_run_in_chat_history_also_leaves_a_receipt()
{
var (fixture, audit, agent) = Aufbau();
var (fixture, audit, agent) = Setup();
var result = await fixture.Engine.ChatAsync(
agent, "Digest", "inst", CancellationToken.None, source: "task", taskId: "t-digest");
@@ -68,9 +68,9 @@ public sealed class BudgetsperreSichtbarTests
}
[Fact]
public async Task Jede_weitere_Ablehnung_des_Tages_steht_als_eigener_Beleg_da()
public async Task Every_further_rejection_of_the_day_stands_as_its_own_receipt()
{
var (fixture, audit, agent) = Aufbau();
var (fixture, audit, agent) = Setup();
for (var i = 0; i < 3; i++)
await fixture.Engine.RunAsync(agent, "Los", "inst", CancellationToken.None, source: "task", taskId: "t-" + i);
@@ -15,7 +15,7 @@ public sealed class BudgetGuardTests : IDisposable
{
private readonly string _directory;
private readonly SqliteUsageRepository _usage;
private readonly DateTime _heute = new(2026, 7, 28, 14, 0, 0, DateTimeKind.Local);
private readonly DateTime _today = new(2026, 7, 28, 14, 0, 0, DateTimeKind.Local);
public BudgetGuardTests()
{
@@ -30,7 +30,7 @@ public sealed class BudgetGuardTests : IDisposable
catch { /* Cleaning up is secondary */ }
}
private BudgetGuard Guard() => new(_usage, () => _heute);
private BudgetGuard Guard() => new(_usage, () => _today);
private static AgentConfig Agent(decimal costLimit = 0, long tokenLimit = 0, string id = "agent-a") => new()
{
@@ -48,7 +48,7 @@ public sealed class BudgetGuardTests : IDisposable
CompletionTokens = completion,
CostUsd = cost,
CostIsKnown = costKnown,
OccurredAt = when ?? _heute
OccurredAt = when ?? _today
}, default);
// ═══════════════════════════════════════════════════════════
@@ -56,7 +56,7 @@ public sealed class BudgetGuardTests : IDisposable
// ═══════════════════════════════════════════════════════════
[Fact]
public async Task Ohne_gesetzte_Grenze_darf_immer_gelaufen_werden()
public async Task Without_a_set_limit_running_is_always_allowed()
{
await Record(cost: 1_000m);
@@ -70,7 +70,7 @@ public sealed class BudgetGuardTests : IDisposable
// ═══════════════════════════════════════════════════════════
[Fact]
public async Task Unterhalb_der_Kostengrenze_laeuft_der_Agent_weiter()
public async Task Below_the_cost_limit_the_agent_keeps_running()
{
await Record(cost: 1.50m);
@@ -80,7 +80,7 @@ public sealed class BudgetGuardTests : IDisposable
}
[Fact]
public async Task Bei_erreichter_Kostengrenze_wird_kein_Lauf_mehr_gestartet()
public async Task Once_the_cost_limit_is_reached_no_run_is_started()
{
await Record(cost: 3m);
await Record(cost: 2m);
@@ -97,7 +97,7 @@ public sealed class BudgetGuardTests : IDisposable
// ═══════════════════════════════════════════════════════════
[Fact]
public async Task Die_Tokengrenze_wirkt_auch_wenn_keine_Preise_vorliegen()
public async Task The_token_limit_applies_even_without_prices()
{
// The actual purpose of the second limit: with an unknown model the
// cost sum stays 0 and a pure cost limit would be ineffective.
@@ -111,7 +111,7 @@ public sealed class BudgetGuardTests : IDisposable
}
[Fact]
public async Task Fehlende_Preise_werden_in_der_Begruendung_erwaehnt()
public async Task Missing_prices_are_mentioned_in_the_reasoning()
{
// Otherwise a low consumption would look like room still left.
await Record(cost: 0m, prompt: 10_000, completion: 1_000, costKnown: false);
@@ -128,7 +128,7 @@ public sealed class BudgetGuardTests : IDisposable
// ═══════════════════════════════════════════════════════════
[Fact]
public async Task Die_Instanzgrenze_zaehlt_alle_Agenten_zusammen()
public async Task The_instance_limit_counts_all_agents_together()
{
await Record(cost: 3m, agentId: "agent-a");
await Record(cost: 3m, agentId: "agent-b");
@@ -142,7 +142,7 @@ public sealed class BudgetGuardTests : IDisposable
}
[Fact]
public async Task Ein_einzelner_Agent_bleibt_unter_der_Instanzgrenze_erlaubt()
public async Task A_single_agent_stays_allowed_under_the_instance_limit()
{
await Record(cost: 2m, agentId: "agent-a");
@@ -157,9 +157,9 @@ public sealed class BudgetGuardTests : IDisposable
// ═══════════════════════════════════════════════════════════
[Fact]
public async Task Der_Verbrauch_des_Vortages_zaehlt_nicht_mit()
public async Task The_previous_days_usage_does_not_count()
{
await Record(cost: 100m, when: _heute.AddDays(-1));
await Record(cost: 100m, when: _today.AddDays(-1));
var status = await Guard().CheckAsync(Agent(costLimit: 5m), InstanceBudget.Unlimited, default);
@@ -167,12 +167,12 @@ public sealed class BudgetGuardTests : IDisposable
}
[Fact]
public async Task Am_naechsten_Tag_steht_das_Budget_wieder_zur_Verfuegung()
public async Task On_the_next_day_the_budget_is_available_again()
{
await Record(cost: 10m);
var morgen = new BudgetGuard(_usage, () => _heute.AddDays(1));
var status = await morgen.CheckAsync(Agent(costLimit: 5m), InstanceBudget.Unlimited, default);
var tomorrow = new BudgetGuard(_usage, () => _today.AddDays(1));
var status = await tomorrow.CheckAsync(Agent(costLimit: 5m), InstanceBudget.Unlimited, default);
status.IsAllowed.ShouldBeTrue();
}
@@ -182,7 +182,7 @@ public sealed class BudgetGuardTests : IDisposable
// ═══════════════════════════════════════════════════════════
[Fact]
public async Task Das_Restbudget_wird_korrekt_berechnet()
public async Task The_remaining_budget_is_calculated_correctly()
{
await Record(cost: 1.25m);
@@ -192,13 +192,13 @@ public sealed class BudgetGuardTests : IDisposable
}
[Fact]
public async Task Ohne_Kostengrenze_gibt_es_kein_Restbudget()
public async Task Without_cost_limit_there_is_no_remaining_budget()
{
(await Guard().GetRemainingCostAsync(Agent(), default)).ShouldBeNull();
}
[Fact]
public async Task Das_Restbudget_wird_nicht_negativ()
public async Task The_remaining_budget_does_not_go_negative()
{
await Record(cost: 20m);
@@ -239,7 +239,7 @@ public sealed class UsageRepositoryTests : IDisposable
}, default);
[Fact]
public async Task Betraege_ueberstehen_den_Rundlauf_ohne_Rundungsfehler()
public async Task Amounts_survive_the_round_trip_without_rounding_errors()
{
// Stored as floating point, cent amounts would add up over thousands
// of runs to a visible error.
@@ -252,7 +252,7 @@ public sealed class UsageRepositoryTests : IDisposable
}
[Fact]
public async Task Der_Tagesverbrauch_summiert_Tokens_und_Laeufe()
public async Task The_daily_usage_sums_tokens_and_runs()
{
await Record(1m);
await Record(2m);
@@ -266,7 +266,7 @@ public sealed class UsageRepositoryTests : IDisposable
}
[Fact]
public async Task Ohne_Agentenfilter_zaehlt_die_ganze_Instanz()
public async Task Without_agent_filter_the_whole_instance_counts()
{
await Record(1m, agentId: "a");
await Record(2m, agentId: "b");
@@ -278,7 +278,7 @@ public sealed class UsageRepositoryTests : IDisposable
}
[Fact]
public async Task Ein_Lauf_ohne_Preisangabe_macht_den_Tag_unvollstaendig()
public async Task A_run_without_price_makes_the_day_incomplete()
{
await Record(1m);
await Record(0m, known: false);
@@ -289,7 +289,7 @@ public sealed class UsageRepositoryTests : IDisposable
}
[Fact]
public async Task Ein_Tag_ohne_Laeufe_ist_leer()
public async Task A_day_without_runs_is_empty()
{
var daily = await _usage.GetDailyAsync(DateOnly.FromDateTime(Tag), "a", default);
@@ -299,7 +299,7 @@ public sealed class UsageRepositoryTests : IDisposable
}
[Fact]
public async Task Alte_Eintraege_lassen_sich_entfernen()
public async Task Old_entries_can_be_removed()
{
await Record(1m, when: Tag.AddDays(-40));
await Record(2m, when: Tag);
@@ -311,7 +311,7 @@ public sealed class UsageRepositoryTests : IDisposable
}
[Fact]
public async Task Viele_Laeufe_koennen_gleichzeitig_erfasst_werden()
public async Task Many_runs_can_be_recorded_concurrently()
{
// The old way rewrote TokenUsage.json completely on every run, under a
// global lock — exactly that did not scale.
@@ -352,11 +352,11 @@ public sealed class FillWorkTests : IDisposable
{
public List<string> Started { get; } = [];
public Task<TaskLauf> DispatchAsync(TaskItem task, CancellationToken ct)
public Task<DispatchOutcome> DispatchAsync(TaskItem task, CancellationToken ct)
{
lock (Started)
Started.Add(task.Id);
return Task.FromResult(TaskLauf.Erledigt);
return Task.FromResult(DispatchOutcome.Erledigt);
}
}
@@ -270,13 +270,13 @@ public sealed class SpecialBudgetTests : IDisposable
public List<string> Instructions { get; } = [];
public List<string> Started { get; } = [];
public Task<TaskLauf> DispatchAsync(TaskItem task, CancellationToken ct)
public Task<DispatchOutcome> DispatchAsync(TaskItem task, CancellationToken ct)
{
Started.Add(task.Id);
return Task.FromResult(TaskLauf.Erledigt);
return Task.FromResult(DispatchOutcome.Erledigt);
}
public async Task<TaskLauf> DispatchAsync(TaskItem task, string? instruction, CancellationToken ct)
public async Task<DispatchOutcome> DispatchAsync(TaskItem task, string? instruction, CancellationToken ct)
{
Started.Add(task.Id);
if (instruction is not null)
@@ -284,7 +284,7 @@ public sealed class SpecialBudgetTests : IDisposable
Instructions.Add(instruction);
await onPlanning(task);
}
return TaskLauf.Erledigt;
return DispatchOutcome.Erledigt;
}
}
}