mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-01 20:07:21 +00:00
Upgraded the tests to NUnit v5.0.0 and awaited their asynchronous assertions
This commit is contained in:
21 files changed
+51
-54
No files matched your search
@@ -65,12 +65,12 @@ public sealed class DataSourceERICancellationTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ACancelledSearchStops()
|
||||
public async Task ACancelledSearchStops()
|
||||
{
|
||||
using var cancellation = new CancellationTokenSource();
|
||||
cancellation.Cancel();
|
||||
|
||||
Assert.CatchAsync<OperationCanceledException>(async () => await UNREACHABLE.RetrieveDataAsync("query", 1, new ChatThread(), cancellation.Token), "Reporting the data source as not searched would carry on after the user cancelled.");
|
||||
await Assert.CatchAsync<OperationCanceledException>(async () => await UNREACHABLE.RetrieveDataAsync("query", 1, new ChatThread(), cancellation.Token), "Reporting the data source as not searched would carry on after the user cancelled.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
+9
-12
@@ -10,29 +10,26 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="10.0.1" />
|
||||
<PackageReference Include="coverlet.collector" Version="10.1.0" />
|
||||
<!--
|
||||
Held at the version the two analyzer projects build against, so that a test compiling a
|
||||
snippet uses the same Roslyn the analyzers themselves were written for. Raise all three
|
||||
together, and never above the Roslyn of the .NET SDK in metadata.txt (5.0 for 10.0.1xx).
|
||||
-->
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.10.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.11.0" />
|
||||
<!--
|
||||
Pinned below 4.6.0 on purpose, verified by bisecting 4.4.0, 4.5.0, 4.5.1, 4.6.0 and 4.6.1
|
||||
against the .NET 9 SDK (9.0.120, C# 13): from 4.6.0 on, the compiler no longer picks
|
||||
Assert.That<TActual>(TActual, IResolveConstraint, ...) for a plain value. 4.6.0 added
|
||||
Assert.That(Action, ...) and Assert.That<T>(Func<T>, ...) alongside it, and the value
|
||||
overload drops out of the candidate set, so even Assert.That(1, Is.EqualTo(1)) fails with
|
||||
"argument 1: cannot convert int to System.Action", a message that points nowhere near the
|
||||
real cause. Re-test the newest version whenever the .NET SDK is raised.
|
||||
NUnit 4.6 broke Assert.That for plain values under C# 13: with Assert.That(Action, ...) added,
|
||||
even Assert.That(1, Is.EqualTo(1)) failed with "argument 1: cannot convert int to System.Action".
|
||||
NUnit 5 with C# 14 picks the value overload again. Should that message come back after an update,
|
||||
this is where it comes from.
|
||||
-->
|
||||
<PackageReference Include="NUnit" Version="4.5.1" />
|
||||
<PackageReference Include="NUnit.Analyzers" Version="4.14.0">
|
||||
<PackageReference Include="NUnit" Version="5.0.0" />
|
||||
<PackageReference Include="NUnit.Analyzers" Version="4.15.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="6.3.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="6.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -233,13 +233,13 @@ public sealed class MailboxIndexStoreTests
|
||||
{
|
||||
var mailId = await this.StoreDocumentAsync(KEY_A);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.ThrowsAsync<ArgumentException>(() => this.Client.UpsertMailAsync(DATA_SOURCE_ID, Mail(mailId), TOKEN), "A mail which lies nowhere would be an orphan from the start.");
|
||||
Assert.ThrowsAsync<ArgumentException>(() => this.Client.UpsertMailAsync(DATA_SOURCE_ID, Mail(mailId, At(INBOX, 7), At(INBOX, 7)), TOKEN));
|
||||
Assert.ThrowsAsync<InvalidOperationException>(() => this.Client.UpsertMailAsync(DATA_SOURCE_ID, Mail(mailId, At("Unknown", 1)), TOKEN));
|
||||
Assert.ThrowsAsync<ArgumentException>(() => this.Client.UpsertMailAsync(DATA_SOURCE_ID, Mail(mailId, At(INBOX, 7)) with { ReferenceMessageIds = ["one two@example.org"] }, TOKEN), "Stored separated by spaces, this one would come back as two.");
|
||||
});
|
||||
await Assert.ThrowsAsync<ArgumentException>(() => this.Client.UpsertMailAsync(DATA_SOURCE_ID, Mail(mailId), TOKEN), "A mail which lies nowhere would be an orphan from the start.");
|
||||
await Assert.ThrowsAsync<ArgumentException>(() => this.Client.UpsertMailAsync(DATA_SOURCE_ID, Mail(mailId, At(INBOX, 7), At(INBOX, 7)), TOKEN));
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => this.Client.UpsertMailAsync(DATA_SOURCE_ID, Mail(mailId, At("Unknown", 1)), TOKEN));
|
||||
await Assert.ThrowsAsync<ArgumentException>(() => this.Client.UpsertMailAsync(DATA_SOURCE_ID, Mail(mailId, At(INBOX, 7)) with { ReferenceMessageIds = ["one two@example.org"] }, TOKEN), "Stored separated by spaces, this one would come back as two.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -91,9 +91,9 @@ public sealed class MailboxStateStoreTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ARemovalOfNoMailIsNothingToHoldBack()
|
||||
public async Task ARemovalOfNoMailIsNothingToHoldBack()
|
||||
{
|
||||
Assert.ThrowsAsync<ArgumentOutOfRangeException>(() => this.Client.HoldBackMailRemovalAsync(DATA_SOURCE_ID, 0, TOKEN));
|
||||
await Assert.ThrowsAsync<ArgumentOutOfRangeException>(() => this.Client.HoldBackMailRemovalAsync(DATA_SOURCE_ID, 0, TOKEN));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -65,10 +65,10 @@ public sealed class FileExportFeedbackTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AnExceptionRemovesTheRunningNotification()
|
||||
public async Task AnExceptionRemovesTheRunningNotification()
|
||||
{
|
||||
var sent = new SentNotifications();
|
||||
Assert.ThrowsAsync<IOException>(async () =>
|
||||
await Assert.ThrowsAsync<IOException>(async () =>
|
||||
{
|
||||
await using var feedback = new FileExportFeedback(sent.Send, _ => Task.CompletedTask);
|
||||
feedback.ShowRunning(FILE_PATH);
|
||||
|
||||
@@ -59,7 +59,7 @@ public class FileTypesTests
|
||||
.ToArray();
|
||||
|
||||
Assert.That(extensions, Is.Not.Empty);
|
||||
Assert.That(extensions, Has.All.Matches<string>(extension => extension == extension.ToLowerInvariant() && !extension.Contains('.')));
|
||||
Assert.That(extensions, Has.All.Matches<string>(extension => extension is not null && extension == extension.ToLowerInvariant() && !extension.Contains('.')));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -90,7 +90,7 @@ public sealed class ImapMailboxConnectorTests
|
||||
// failure instead of this one.
|
||||
//
|
||||
await using var connector = new ImapMailboxConnector();
|
||||
var exception = Assert.ThrowsAsync<MailboxConnectionException>(() => connector.ConnectAsync(mailbox, password, MailServerPolicy.ANY_SERVER, CancellationToken.None));
|
||||
var exception = await Assert.ThrowsAsync<MailboxConnectionException>(() => connector.ConnectAsync(mailbox, password, MailServerPolicy.ANY_SERVER, CancellationToken.None));
|
||||
Assert.That(exception?.Failure, Is.EqualTo(MailboxConnectionFailure.INVALID_SETTINGS));
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public sealed class ImapMailboxConnectorTests
|
||||
//
|
||||
await using var connector = new ImapMailboxConnector();
|
||||
var policy = new MailServerPolicy(true, ["imap.intra.example.org"]);
|
||||
var exception = Assert.ThrowsAsync<MailboxConnectionException>(() => connector.ConnectAsync(MAILBOX, PASSWORD, policy, CancellationToken.None));
|
||||
var exception = await Assert.ThrowsAsync<MailboxConnectionException>(() => connector.ConnectAsync(MAILBOX, PASSWORD, policy, CancellationToken.None));
|
||||
Assert.That(exception?.Failure, Is.EqualTo(MailboxConnectionFailure.SERVER_NOT_ALLOWED));
|
||||
}
|
||||
|
||||
|
||||
@@ -61,22 +61,22 @@ public sealed class MailAttachmentPiecesTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AnUnknownEncodingFetchesNothing()
|
||||
public async Task AnUnknownEncodingFetchesNothing()
|
||||
{
|
||||
var server = new PieceServer(Encoding.ASCII.GetBytes("Uryyb"));
|
||||
Assert.Multiple(() =>
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.ThrowsAsync<InvalidDataException>(async () => await WriteDecodedAsync(server, "x-rot13"));
|
||||
await Assert.ThrowsAsync<InvalidDataException>(async () => await WriteDecodedAsync(server, "x-rot13"));
|
||||
Assert.That(server.RequestedOffsets, Is.Empty);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void APieceLargerThanAskedForIsRefused()
|
||||
public async Task APieceLargerThanAskedForIsRefused()
|
||||
{
|
||||
// Taken as it came, the next piece would repeat what this one already delivered:
|
||||
var server = new PieceServer(new byte[100], deliveredBytes: PIECE_BYTES + 1);
|
||||
Assert.ThrowsAsync<InvalidDataException>(async () => await WriteDecodedAsync(server, "binary"));
|
||||
await Assert.ThrowsAsync<InvalidDataException>(async () => await WriteDecodedAsync(server, "binary"));
|
||||
}
|
||||
|
||||
private static async Task<byte[]> WriteDecodedAsync(PieceServer server, string? transferEncoding)
|
||||
|
||||
@@ -97,11 +97,11 @@ public sealed class TranscriptPromptInjectionTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OnlyAReadyTranscriptCanBeRead()
|
||||
public async Task OnlyAReadyTranscriptCanBeRead()
|
||||
{
|
||||
var transcript = PersistentMediaTranscriptResult.Unavailable(PersistentMediaTranscriptStatus.NO_PROVIDER, null, "No provider.");
|
||||
|
||||
Assert.ThrowsAsync<ArgumentException>(() => PersistentMediaTranscript.ReadTranscriptAsync(this.rustService, transcript, this.mediaPath, reportingScope: null, CancellationToken.None));
|
||||
await Assert.ThrowsAsync<ArgumentException>(() => PersistentMediaTranscript.ReadTranscriptAsync(this.rustService, transcript, this.mediaPath, reportingScope: null, CancellationToken.None));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -117,12 +117,12 @@ public sealed class PassageProvenanceTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StoringNeverStopsTheAnswer()
|
||||
public async Task StoringNeverStopsTheAnswer()
|
||||
{
|
||||
// A passage without its text, as an ERI server sent one before its fields were checked:
|
||||
var answer = new ContentText { SourcePassages = [Passage(HANDBOOK_URL, null!)] };
|
||||
|
||||
Assert.DoesNotThrowAsync(() => answer.StoreReceivedContentAsync(Guid.NewGuid()), "Completing the answer waits for this, and a throw left its chat running until the app restarted.");
|
||||
await Assert.DoesNotThrowAsync(() => answer.StoreReceivedContentAsync(Guid.NewGuid()), "Completing the answer waits for this, and a throw left its chat running until the app restarted.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -163,11 +163,11 @@ public sealed class RetrievalPagingTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AnERIDataSourceRefusesAFurtherPage()
|
||||
public async Task AnERIDataSourceRefusesAFurtherPage()
|
||||
{
|
||||
var source = new DataSourceERI_V1 { Id = "33333333-3333-3333-3333-333333333333", Name = "Intranet", MaxMatches = 10 };
|
||||
|
||||
Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await source.RetrieveDataAsync("query", 2, new AIStudio.Chat.ChatThread()));
|
||||
await Assert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await source.RetrieveDataAsync("query", 2, new AIStudio.Chat.ChatThread()));
|
||||
}
|
||||
|
||||
private static (IReadOnlyList<string> Matches, bool HasMore) Merge(string[] first, string[] second, int page)
|
||||
|
||||
@@ -158,5 +158,5 @@ public sealed class CountMailsToolTests : ToolRegistryTestBase
|
||||
|
||||
private static JsonElement Arguments(string json) => JsonSerializer.Deserialize<JsonElement>(json);
|
||||
|
||||
private static string Refusal(TestDelegate read) => Assert.Throws<ArgumentException>(read)!.Message;
|
||||
private static string Refusal(Action read) => Assert.Throws<ArgumentException>(read)!.Message;
|
||||
}
|
||||
@@ -223,7 +223,7 @@ public sealed class MailToolArgumentsTests
|
||||
|
||||
private static JsonElement Arguments(string json) => JsonSerializer.Deserialize<JsonElement>(json);
|
||||
|
||||
private static string Refusal(TestDelegate read) => Assert.Throws<ArgumentException>(read)!.Message;
|
||||
private static string Refusal(Action read) => Assert.Throws<ArgumentException>(read)!.Message;
|
||||
|
||||
/// <summary>
|
||||
/// A time zone two hours ahead of UTC, all year round, so that no test depends on the computer or on daylight saving time.
|
||||
|
||||
@@ -194,5 +194,5 @@ public sealed class ReadMailToolTests : ToolRegistryTestBase
|
||||
|
||||
private static JsonElement Arguments(string json) => JsonSerializer.Deserialize<JsonElement>(json);
|
||||
|
||||
private static string Refusal(TestDelegate read) => Assert.Throws<ArgumentException>(read)!.Message;
|
||||
private static string Refusal(Action read) => Assert.Throws<ArgumentException>(read)!.Message;
|
||||
}
|
||||
@@ -149,11 +149,11 @@ public sealed class ReadWebPageAllowedPrivateHostTests : ToolRegistryTestBase
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AnAllowedNameWhichResolvesToAPublicAddressIsRefused()
|
||||
public async Task AnAllowedNameWhichResolvesToAPublicAddressIsRefused()
|
||||
{
|
||||
var service = new WebPageRetrievalService(new HTMLParser());
|
||||
|
||||
var exception = Assert.ThrowsAsync<WebPageAccessBlockedException>(() => service.RetrieveAsync(new Uri(PUBLIC_ADDRESS), new WebPageRetrievalOptions
|
||||
var exception = await Assert.ThrowsAsync<WebPageAccessBlockedException>(() => service.RetrieveAsync(new Uri(PUBLIC_ADDRESS), new WebPageRetrievalOptions
|
||||
{
|
||||
TimeoutSeconds = 10,
|
||||
ProviderConfidence = ConfidenceLevel.HIGH,
|
||||
@@ -165,7 +165,7 @@ public sealed class ReadWebPageAllowedPrivateHostTests : ToolRegistryTestBase
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ARedirectFromAnAllowedPrivateHostToAPublicAddressIsRefused()
|
||||
public async Task ARedirectFromAnAllowedPrivateHostToAPublicAddressIsRefused()
|
||||
{
|
||||
using var server = new LoopbackWebServer(redirectLocation: PUBLIC_ADDRESS);
|
||||
var service = new WebPageRetrievalService(new HTMLParser());
|
||||
@@ -175,7 +175,7 @@ public sealed class ReadWebPageAllowedPrivateHostTests : ToolRegistryTestBase
|
||||
// chose only, which the limit holds for all the same, because it guards what the address
|
||||
// may carry:
|
||||
//
|
||||
var exception = Assert.ThrowsAsync<WebPageAccessBlockedException>(() => service.RetrieveAsync(server.Address("/redirect"), new WebPageRetrievalOptions
|
||||
var exception = await Assert.ThrowsAsync<WebPageAccessBlockedException>(() => service.RetrieveAsync(server.Address("/redirect"), new WebPageRetrievalOptions
|
||||
{
|
||||
TimeoutSeconds = 10,
|
||||
TargetChosenByUser = true,
|
||||
|
||||
@@ -94,7 +94,7 @@ public sealed class ReadWebPageFreeAddressChoiceTests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OffRefusesAMadeUpAddressWithoutRepeatingIt()
|
||||
public async Task OffRefusesAMadeUpAddressWithoutRepeatingIt()
|
||||
{
|
||||
var tool = new ReadWebPageTool(null!, null!, null!, NullLogger<ReadWebPageTool>.Instance);
|
||||
using var arguments = JsonDocument.Parse("""{"url":"https://made-up.example/?question=budget"}""");
|
||||
@@ -109,7 +109,7 @@ public sealed class ReadWebPageFreeAddressChoiceTests
|
||||
SettingsValues = new Dictionary<string, string>(),
|
||||
};
|
||||
|
||||
var exception = Assert.ThrowsAsync<ToolExecutionBlockedException>(() => tool.ExecuteAsync(arguments.RootElement, context));
|
||||
var exception = await Assert.ThrowsAsync<ToolExecutionBlockedException>(() => tool.ExecuteAsync(arguments.RootElement, context));
|
||||
|
||||
Assert.That(exception!.Message, Does.Contain("Free address choice is off").And.Not.Contain("made-up").And.Not.Contain("budget"), "Repeated in the result, the address would stand in the chat afterwards.");
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ public sealed class ReadWebPageOutboundDataRestrictionTests : ToolRegistryTestBa
|
||||
Assert.That(ReadWebPageTool.IsAllowedByOutboundDataRestriction(new Uri(GIVEN), (OutboundDataRestriction)99, ChatWithTheUserWriting(GIVEN), WIKI_URL, NO_PRIVATE_HOSTS, out _), Is.False);
|
||||
|
||||
[Test]
|
||||
public void ARefusalDoesNotRepeatTheAddress()
|
||||
public async Task ARefusalDoesNotRepeatTheAddress()
|
||||
{
|
||||
//
|
||||
// Repeated in the result of a call, the address would stand in the chat afterwards, and the
|
||||
@@ -98,7 +98,7 @@ public sealed class ReadWebPageOutboundDataRestrictionTests : ToolRegistryTestBa
|
||||
var chat = RestrictedChat(OutboundDataRestriction.ONLY_LINKS_FROM_CHAT);
|
||||
using var arguments = JsonDocument.Parse("""{"url":"https://attacker.example/?mail=board-meeting"}""");
|
||||
|
||||
var exception = Assert.ThrowsAsync<ToolExecutionBlockedException>(() => tool.ExecuteAsync(arguments.RootElement, this.ExecutionContext(tool, chat)));
|
||||
var exception = await Assert.ThrowsAsync<ToolExecutionBlockedException>(() => tool.ExecuteAsync(arguments.RootElement, this.ExecutionContext(tool, chat)));
|
||||
|
||||
Assert.That(exception!.Message, Does.Not.Contain("attacker").And.Not.Contain("board-meeting"));
|
||||
}
|
||||
|
||||
@@ -324,5 +324,5 @@ public sealed class SearchMailsToolTests : ToolRegistryTestBase
|
||||
|
||||
private static JsonElement Arguments(string json) => JsonSerializer.Deserialize<JsonElement>(json);
|
||||
|
||||
private static string Refusal(TestDelegate read) => Assert.Throws<ArgumentException>(read)!.Message;
|
||||
private static string Refusal(Action read) => Assert.Throws<ArgumentException>(read)!.Message;
|
||||
}
|
||||
@@ -115,5 +115,5 @@ public sealed class SemanticSearchToolRequestTests
|
||||
/// <summary>
|
||||
/// Reads a search which has to be refused and returns what the refusal said.
|
||||
/// </summary>
|
||||
private static string Refusal(TestDelegate read) => Assert.Throws<ArgumentException>(read)!.Message;
|
||||
private static string Refusal(Action read) => Assert.Throws<ArgumentException>(read)!.Message;
|
||||
}
|
||||
@@ -163,5 +163,5 @@ public sealed class ToolArgumentReaderTests
|
||||
/// <summary>
|
||||
/// Runs a reader which has to refuse its argument and returns what it said.
|
||||
/// </summary>
|
||||
private static string Refusal(TestDelegate read) => Assert.Throws<ArgumentException>(read)!.Message;
|
||||
private static string Refusal(Action read) => Assert.Throws<ArgumentException>(read)!.Message;
|
||||
}
|
||||
@@ -166,5 +166,5 @@ public sealed class WebSearchToolArgumentTests
|
||||
/// <summary>
|
||||
/// Runs a reader which has to refuse its argument and returns what it said.
|
||||
/// </summary>
|
||||
private static string Refusal(TestDelegate read) => Assert.Throws<ArgumentException>(read)!.Message;
|
||||
private static string Refusal(Action read) => Assert.Throws<ArgumentException>(read)!.Message;
|
||||
}
|
||||
Reference in new issue
Block a user