Files
davideandClaude Sonnet 5.5 5870de6fda FakeClaude, test per area e renderer diviso in due file
- tests/FakeClaude: eseguibile finto 'claude' configurabile con variabili
  d'ambiente (registro di argomenti/cwd/stdin, output, exit code, ritardo),
  con le prove FK-01…FK-05.
- Test organizzati per livello (Gui/, Process/, Support/) e struttura
  descritta in TESTING.md.
- MarkdownView: la parte sulle immagini passa in MarkdownView.Images.cs
  (partial), senza cambiare il comportamento.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-15 16:00:25 +02:00

90 lines
3.2 KiB
C#

using System.Diagnostics;
using System.Text.Json;
namespace AgentWikiUi.Tests;
/// <summary>Il doppio di test di <c>claude</c> (docs/TESTING.md → FakeClaude, FK-01…FK-05).</summary>
[Trait("Category", "Process")]
public sealed class FakeClaudeTests : IDisposable
{
readonly string dir = Directory.CreateTempSubdirectory("awui-fake-").FullName;
public void Dispose() => Directory.Delete(dir, true);
string LogPath => Path.Combine(dir, "log.jsonl");
Process Start(IEnumerable<string> args, Dictionary<string, string>? env = null, string? cwd = null)
{
var psi = new ProcessStartInfo(FakeClaudePath.Exe)
{
UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true,
WorkingDirectory = cwd ?? dir,
};
foreach (var a in args) psi.ArgumentList.Add(a);
psi.Environment["FAKE_CLAUDE_LOG"] = LogPath;
foreach (var (k, v) in env ?? []) psi.Environment[k] = v;
return Process.Start(psi)!;
}
[Fact]
public void Registra_argomenti_cwd_e_stdin()
{
var cwd = Directory.CreateDirectory(Path.Combine(dir, "lavoro")).FullName;
using var p = Start(["-p", "dì \"ciao\" a tutti", "--model", "m"], cwd: cwd);
p.StandardInput.Write("dati da stdin");
p.StandardInput.Close();
Assert.True(p.WaitForExit(10_000));
using var line = JsonDocument.Parse(File.ReadAllLines(LogPath).Single());
var r = line.RootElement;
Assert.Equal(["-p", "dì \"ciao\" a tutti", "--model", "m"], r.GetProperty("args").EnumerateArray().Select(a => a.GetString()));
Assert.Equal(cwd, r.GetProperty("cwd").GetString());
Assert.Equal("dati da stdin", r.GetProperty("stdin").GetString());
}
[Fact]
public void Output_e_stderr_configurati()
{
using var p = Start([], new() { ["FAKE_CLAUDE_OUT"] = "risposta", ["FAKE_CLAUDE_ERR"] = "avviso" });
p.StandardInput.Close();
Assert.Equal("risposta", p.StandardOutput.ReadToEnd());
Assert.Equal("avviso", p.StandardError.ReadToEnd());
Assert.True(p.WaitForExit(10_000));
}
[Theory]
[InlineData(null, 0)]
[InlineData("3", 3)]
[InlineData("127", 127)]
public void ExitCode_configurato(string? configured, int expected)
{
using var p = Start([], configured is null ? null : new() { ["FAKE_CLAUDE_EXIT"] = configured });
p.StandardInput.Close();
Assert.True(p.WaitForExit(10_000));
Assert.Equal(expected, p.ExitCode);
}
[Fact]
public void Ritardo_configurato()
{
using var p = Start([], new() { ["FAKE_CLAUDE_DELAY_MS"] = "600" });
var sw = Stopwatch.StartNew();
p.StandardInput.Close();
Assert.True(p.WaitForExit(10_000));
Assert.True(sw.ElapsedMilliseconds >= 500, $"terminato dopo {sw.ElapsedMilliseconds} ms");
}
[Fact]
public void Attende_la_chiusura_di_stdin()
{
using var p = Start([]);
try
{
Assert.False(p.WaitForExit(700), "il processo è terminato con stdin ancora aperto");
p.StandardInput.Close();
Assert.True(p.WaitForExit(10_000));
}
finally { if (!p.HasExited) p.Kill(); }
}
}