Upgraded to .NET 10 (#1147)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2026-11-01 20:32:16 +01:00
1 parent faae2951f7
commit fc7399e81b
327 files changed
+3059 -3049

No files matched your search

@@ -25,13 +25,13 @@ public sealed class BatchProcessingOutputFolderTests
{
var outputFolder = new BatchProcessingOutputFolder(INPUT_FOLDER, PROJECT_FOLDER, RESULTS_FILE_NAME);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "report.pdf")), Is.False);
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "notes", "minutes.md")), Is.False);
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "log.csv")), Is.False, "The log of a run lies in the output folder, so a file of this name in the input folder is a document.");
Assert.That(outputFolder.Enters(Path.Combine(INPUT_FOLDER, "notes")), Is.True);
});
}
}
[Test]
@@ -39,12 +39,12 @@ public sealed class BatchProcessingOutputFolderTests
{
var outputFolder = new BatchProcessingOutputFolder(INPUT_FOLDER, DESKTOP, RESULTS_FILE_NAME);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "report.pdf")), Is.False);
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "notes", "minutes.md")), Is.False);
Assert.That(outputFolder.Enters(Path.Combine(INPUT_FOLDER, "notes")), Is.True);
});
}
}
[Test]
@@ -53,13 +53,13 @@ public sealed class BatchProcessingOutputFolderTests
var resultsFolder = Path.Combine(INPUT_FOLDER, "ai-results");
var outputFolder = new BatchProcessingOutputFolder(INPUT_FOLDER, resultsFolder, RESULTS_FILE_NAME);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(resultsFolder, "report_result.md")), Is.True);
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "report.pdf")), Is.False);
Assert.That(outputFolder.Enters(resultsFolder), Is.False);
Assert.That(outputFolder.Enters(Path.Combine(INPUT_FOLDER, "notes")), Is.True);
});
}
}
[Test]
@@ -69,14 +69,14 @@ public sealed class BatchProcessingOutputFolderTests
var resultsFolder = Path.Combine(parentFolder, "results");
var outputFolder = new BatchProcessingOutputFolder(INPUT_FOLDER, resultsFolder, RESULTS_FILE_NAME);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(resultsFolder, "report_result.md")), Is.True);
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(parentFolder, "report.pdf")), Is.False);
Assert.That(outputFolder.Enters(Path.Combine(INPUT_FOLDER, "2026")), Is.True);
Assert.That(outputFolder.Enters(parentFolder), Is.True);
Assert.That(outputFolder.Enters(resultsFolder), Is.False);
});
}
}
[Test]
@@ -84,11 +84,11 @@ public sealed class BatchProcessingOutputFolderTests
{
var outputFolder = new BatchProcessingOutputFolder(INPUT_FOLDER, Path.Combine(INPUT_FOLDER, "out"), RESULTS_FILE_NAME);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "output-notes.md")), Is.False);
Assert.That(outputFolder.Enters(Path.Combine(INPUT_FOLDER, "output")), Is.True);
});
}
}
[Test]
@@ -96,12 +96,12 @@ public sealed class BatchProcessingOutputFolderTests
{
var outputFolder = new BatchProcessingOutputFolder(INPUT_FOLDER, $"{INPUT_FOLDER}-results", RESULTS_FILE_NAME);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "report.pdf")), Is.False);
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "log.csv")), Is.False);
Assert.That(outputFolder.Enters(Path.Combine(INPUT_FOLDER, "notes")), Is.True);
});
}
}
[TestCase(false)]
@@ -111,13 +111,13 @@ public sealed class BatchProcessingOutputFolderTests
var outputDirectory = withTrailingSeparator ? INPUT_FOLDER + Path.DirectorySeparatorChar : INPUT_FOLDER;
var outputFolder = new BatchProcessingOutputFolder(INPUT_FOLDER, outputDirectory, RESULTS_FILE_NAME);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "log.csv")), Is.True);
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, RESULTS_FILE_NAME)), Is.True);
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "report.pdf")), Is.False);
Assert.That(outputFolder.Enters(Path.Combine(INPUT_FOLDER, "notes")), Is.True, "Leaving out the output folder would leave out the input folder, too.");
});
}
}
[Test]
@@ -125,13 +125,13 @@ public sealed class BatchProcessingOutputFolderTests
{
var outputFolder = new BatchProcessingOutputFolder(INPUT_FOLDER, INPUT_FOLDER, RESULTS_FILE_NAME);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "report_result.md")), Is.True);
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "report_result_2.docx")), Is.True, "A second result of the same name gets a counter.");
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "Report_Result.HTML")), Is.True);
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "report.v2_result.md")), Is.True, "Only the last extension of the document makes way for the suffix.");
});
}
}
[Test]
@@ -139,14 +139,14 @@ public sealed class BatchProcessingOutputFolderTests
{
var outputFolder = new BatchProcessingOutputFolder(INPUT_FOLDER, INPUT_FOLDER, RESULTS_FILE_NAME);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "report.md")), Is.False);
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "result.md")), Is.False);
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "my_results.md")), Is.False);
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "report_result_draft.md")), Is.False);
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(INPUT_FOLDER, "report_result_.md")), Is.False);
});
}
}
[Test]
@@ -155,11 +155,11 @@ public sealed class BatchProcessingOutputFolderTests
var outputFolder = new BatchProcessingOutputFolder(INPUT_FOLDER, INPUT_FOLDER, RESULTS_FILE_NAME);
var subfolder = Path.Combine(INPUT_FOLDER, "notes");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(subfolder, "log.csv")), Is.False, "A run writes into the output folder itself, never into one of its subfolders.");
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(subfolder, RESULTS_FILE_NAME)), Is.False);
Assert.That(outputFolder.IsOutputOfRun(Path.Combine(subfolder, "report_result.md")), Is.False);
});
}
}
}
@@ -32,11 +32,11 @@ public sealed class ERIServerFileListTests
var isRead = ERIServerFileList.TryParse(ANSWER, out var files);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(isRead, Is.True);
Assert.That(files, Is.EqualTo(FILES));
});
}
}
[Test]
@@ -44,11 +44,11 @@ public sealed class ERIServerFileListTests
{
var isRead = ERIServerFileList.TryParse("""{ "files": [ "src\\main.py" ] }""", out var files);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(isRead, Is.True);
Assert.That(files, Is.EqualTo(PATH_WITH_BACKSLASH));
});
}
}
[Test]
@@ -56,11 +56,11 @@ public sealed class ERIServerFileListTests
{
var isRead = ERIServerFileList.TryParse("""{ "files": [ "main.py", "", " " ] }""", out var files);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(isRead, Is.True);
Assert.That(files, Is.EqualTo(MAIN_PY));
});
}
}
[TestCase("""[ "main.py" ]""", TestName = "A list without its object")]
@@ -73,10 +73,10 @@ public sealed class ERIServerFileListTests
{
var isRead = ERIServerFileList.TryParse(answer, out var files);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(isRead, Is.False);
Assert.That(files, Is.Empty);
});
}
}
}
@@ -45,11 +45,11 @@ public sealed class ERIServerFileWritingTests
{
var outcome = await ERIServerFiles.WriteAsync(this.baseDirectory, "src/my-server/main.py", ANSWER, NullLogger.Instance);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(outcome, Is.EqualTo(ERIServerFileOutcome.WRITTEN));
Assert.That(File.ReadAllText(Path.Join(this.baseDirectory, "src", "my-server", "main.py")), Is.EqualTo(MAIN_PY));
});
}
}
[Test]
@@ -58,11 +58,11 @@ public sealed class ERIServerFileWritingTests
var file = $"../outside-{Guid.NewGuid():N}.py";
var outcome = await ERIServerFiles.WriteAsync(this.baseDirectory, file, ANSWER, NullLogger.Instance);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(outcome, Is.EqualTo(ERIServerFileOutcome.OUTSIDE_BASE_DIRECTORY));
Assert.That(File.Exists(Path.GetFullPath(Path.Join(this.baseDirectory, file))), Is.False);
});
}
}
[Test]
@@ -70,11 +70,11 @@ public sealed class ERIServerFileWritingTests
{
var outcome = await ERIServerFiles.WriteAsync(this.baseDirectory, "main.py", "## main.py\n\n```python\nprint(", NullLogger.Instance);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(outcome, Is.EqualTo(ERIServerFileOutcome.NO_COMPLETE_CODE_BLOCK));
Assert.That(File.Exists(Path.Join(this.baseDirectory, "main.py")), Is.False);
});
}
}
[Test]
@@ -51,11 +51,11 @@ public sealed class ERIServerPromptTests
{
var lines = Lines(new ERIServerPrompt { AuthenticationMethods = [Auth.NONE, Auth.USERNAME_PASSWORD], AuthDescription = AUTH_DESCRIPTION });
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(lines, Does.Contain("The authentication process is planned as follows:"));
Assert.That(lines, Does.Contain(AUTH_DESCRIPTION));
});
}
}
[Test]
@@ -36,7 +36,7 @@ public sealed class SwotAnalysisContentPresentationTests
var restoredContent = (ContentText)restoredThread!.Blocks.Single().Content!;
var presentationWasRead = SwotAnalysisContentPresentation.TryRead(restoredContent.Presentation, out var restoredResult);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(clone.Presentation, Is.Not.SameAs(content.Presentation));
Assert.That(clone.Text, Is.EqualTo(content.Text));
@@ -45,7 +45,7 @@ public sealed class SwotAnalysisContentPresentationTests
Assert.That(restoredResult.MatrixHeading, Is.EqualTo("SWOT Matrix"));
Assert.That(restoredResult.Strengths.Findings.Single().Summary, Is.EqualTo("Experienced team"));
Assert.That(restoredResult.PrioritizedActions.Items.Single().Action, Is.EqualTo("Prepare expansion"));
});
}
}
[Test]
@@ -59,11 +59,11 @@ public sealed class SwotAnalysisContentPresentationTests
var presentationWasRead = SwotAnalysisContentPresentation.TryRead(content.Presentation, out _);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(presentationWasRead, Is.False);
Assert.That(content.Text, Is.EqualTo("Fallback Markdown"));
});
}
}
[Test]
@@ -90,12 +90,12 @@ public sealed class SwotAnalysisContentPresentationTests
var presentationWasRead = SwotAnalysisContentPresentation.TryRead(content.Presentation, out var readResult);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(presentationWasRead, Is.True);
Assert.That(readResult.Categories.All(category => category.Findings.Count == 0), Is.True);
Assert.That(readResult.PrioritizedActions.Items, Is.Empty);
});
}
}
[Test]
@@ -16,7 +16,7 @@ public sealed class SwotAnalysisMarkdownFormatterTests
var markdown = SwotAnalysisMarkdownFormatter.Format(result);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(markdown, Does.Contain("| | Positive | Negative |"));
Assert.That(Count(markdown, "Experienced team"), Is.GreaterThanOrEqualTo(2));
@@ -26,7 +26,7 @@ public sealed class SwotAnalysisMarkdownFormatterTests
Assert.That(markdown.IndexOf("## SWOT Matrix", StringComparison.Ordinal), Is.LessThan(markdown.IndexOf("## Strengths", StringComparison.Ordinal)));
Assert.That(markdown.IndexOf("## SWOT Matrix", StringComparison.Ordinal), Is.LessThan(markdown.IndexOf("## Prioritized Actions", StringComparison.Ordinal)));
Assert.That(markdown, Does.Contain("| **External** | **Opportunities:** Growing market | **Threats:** New competitor |"));
});
}
}
[Test]
@@ -45,13 +45,13 @@ public sealed class SwotAnalysisMarkdownFormatterTests
.Select(heading => markdown.IndexOf(heading, StringComparison.Ordinal))
.ToList();
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(positions, Is.All.GreaterThanOrEqualTo(0));
Assert.That(positions, Is.Ordered);
Assert.That(markdown, Does.Contain("The position is solid\\.\n\nThe competitor is the main risk\\."));
Assert.That(markdown, Does.EndWith("- **Moved the new competitor to the threats\\.** — It is external and negative\\."));
});
}
}
[Test]
@@ -13,7 +13,7 @@ public sealed class SwotAnalysisModerationTests
var parsed = SwotAnalysisModerationResponseParser.TryParse(JsonSerializer.Serialize(CreateModeration()), out var moderation, out var issue);
var result = SwotAnalysisModeration.Assemble(moderation);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(parsed, Is.True);
Assert.That(issue, Is.Empty);
@@ -23,7 +23,7 @@ public sealed class SwotAnalysisModerationTests
Assert.That(result.OverallAssessment.Paragraphs, Is.EqualTo(new[] { "The position is solid.", "The competitor is the main risk." }));
Assert.That(result.ModerationNotes.Items.Single().Change, Is.EqualTo("Merged two strengths about the team."));
Assert.That(result.PrioritizedActions.Items.Single().AddressedFactors, Is.EqualTo(new[] { "Experienced team", "Growing market" }));
});
}
}
[Test]
@@ -34,11 +34,11 @@ public sealed class SwotAnalysisModerationTests
var parsed = SwotAnalysisModerationResponseParser.TryParse(JsonSerializer.Serialize(moderation), out var parsedModeration, out _);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(parsed, Is.True);
Assert.That(SwotAnalysisModeration.Assemble(parsedModeration).PrioritizedActions.Items.Single().AddressedFactors, Is.EqualTo(new[] { "Experienced team", "Growing market" }));
});
}
}
[Test]
@@ -47,11 +47,11 @@ public sealed class SwotAnalysisModerationTests
var moderation = CreateModeration();
moderation.Strengths.Findings.Single().FactorId = "W2";
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(SwotAnalysisModerationResponseParser.TryParse(JsonSerializer.Serialize(moderation), out _, out var issue), Is.False);
Assert.That(issue, Is.EqualTo("Finding 1 of strengths has the factor_id \"W2\", which does not start with \"S\"."));
});
}
}
[Test]
@@ -60,11 +60,11 @@ public sealed class SwotAnalysisModerationTests
var moderation = CreateModeration();
moderation.Strengths.Findings.Add(Finding("s1", "Loyal customers", "The survey shows long customer relationships."));
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(SwotAnalysisModerationResponseParser.TryParse(JsonSerializer.Serialize(moderation), out _, out var issue), Is.False);
Assert.That(issue, Does.Contain("\"s1\" is used more than once"));
});
}
}
[Test]
@@ -73,11 +73,11 @@ public sealed class SwotAnalysisModerationTests
var moderation = CreateModeration();
moderation.PrioritizedActions.Items.Single().AddressedFactorIds = ["S1", "X9"];
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(SwotAnalysisModerationResponseParser.TryParse(JsonSerializer.Serialize(moderation), out _, out var issue), Is.False);
Assert.That(issue, Does.Contain("\"X9\""));
});
}
}
[Test]
@@ -86,11 +86,11 @@ public sealed class SwotAnalysisModerationTests
var moderation = CreateModeration();
moderation.OverallAssessment.Text = " ";
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(SwotAnalysisModerationResponseParser.TryParse(JsonSerializer.Serialize(moderation), out _, out var issue), Is.False);
Assert.That(issue, Is.EqualTo("The field overall_assessment.text is empty."));
});
}
}
[Test]
@@ -102,22 +102,22 @@ public sealed class SwotAnalysisModerationTests
withReason.ModerationNotes.Items.Clear();
withReason.ModerationNotes.EmptyMessage = "The four categories needed no changes.";
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(SwotAnalysisModerationResponseParser.TryParse(JsonSerializer.Serialize(withoutReason), out _, out var issue), Is.False);
Assert.That(issue, Does.StartWith("moderation_notes has no items"));
Assert.That(SwotAnalysisModerationResponseParser.TryParse(JsonSerializer.Serialize(withReason), out _, out _), Is.True);
});
}
}
[Test]
public void AnAnswerWithoutJsonNamesTheProblemForTheModel()
{
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(SwotAnalysisModerationResponseParser.TryParse("Here is my assessment.", out _, out var issue), Is.False);
Assert.That(issue, Does.Contain("no complete JSON object"));
});
}
}
[Test]
@@ -125,7 +125,7 @@ public sealed class SwotAnalysisModerationTests
{
var request = SwotAnalysisModeration.BuildUserRequest(CreateCategories(), "Support the investment decision", string.Empty, "A market report documents increasing demand.");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
foreach (var category in new[] { "strengths", "weaknesses", "opportunities", "threats" })
Assert.That(request, Does.Contain($"\"{category}\""));
@@ -137,7 +137,7 @@ public sealed class SwotAnalysisModerationTests
Assert.That(request, Does.Match("(?s)<analysis-focus>\\s*No additional analysis focus was provided\\.\\s*</analysis-focus>"));
Assert.That(request, Does.Match("(?s)<shared-research>\\s*A market report documents increasing demand\\.\\s*</shared-research>"));
Assert.That(request, Does.Not.Contain("<analysis-subject>"), "The moderator works on the results, not on the material.");
});
}
}
[Test]
@@ -149,13 +149,13 @@ public sealed class SwotAnalysisModerationTests
{
var prompt = SwotAnalysisModeration.BuildSystemPrompt("Answer in German.");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
foreach (var key in new[] { "\"moderation_notes\"", "\"overall_assessment\"", "\"prioritized_actions\"", "\"addressed_factor_ids\"", "\"factor_id\"" })
Assert.That(prompt, Does.Contain(key));
Assert.That(prompt, Does.EndWith("Answer in German."));
});
}
}
private static Dictionary<SwotAnalysisCategory, SwotCategoryAnalysisResult> CreateCategories() => new()
@@ -18,7 +18,7 @@ public sealed class SwotAnalysisSendToChatTests
var chatThread = AssistantSWOTAnalysis.CreateChatThreadForResult(assistantThread, visiblePrompt, result);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(chatThread.Blocks, Has.Count.EqualTo(2));
Assert.That(chatThread.Blocks[0], Is.SameAs(visiblePrompt));
@@ -27,7 +27,7 @@ public sealed class SwotAnalysisSendToChatTests
Assert.That(((ContentText)chatThread.Blocks[1].Content!).Text, Is.EqualTo("## SWOT Matrix"));
Assert.That(chatThread.Blocks[1].Content, Is.Not.SameAs(result.Content));
Assert.That(chatThread.SystemPrompt, Is.EqualTo(SystemPrompts.DEFAULT));
});
}
}
[Test]
@@ -38,11 +38,11 @@ public sealed class SwotAnalysisSendToChatTests
var chatThread = AssistantSWOTAnalysis.CreateChatThreadForResult(assistantThread, VisiblePrompt(result.Time.AddTicks(-1)), result);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(assistantThread.IsWebAddressGivenToTheModel(new Uri(ADDRESS_A_MODEL_CHOSE)), Is.True, "The hidden request counts as a message of the user.");
Assert.That(chatThread.IsWebAddressGivenToTheModel(new Uri(ADDRESS_A_MODEL_CHOSE)), Is.False);
});
}
}
[Test]
@@ -54,11 +54,11 @@ public sealed class SwotAnalysisSendToChatTests
var chatThread = AssistantSWOTAnalysis.CreateChatThreadForResult(assistantThread, VisiblePrompt(result.Time.AddTicks(-1)), result);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(chatThread.ChatId, Is.EqualTo(assistantThread.ChatId));
Assert.That(chatThread.RequiredProviderConfidence, Is.EqualTo(ConfidenceLevel.HIGH));
});
}
}
[Test]
@@ -21,12 +21,12 @@ public sealed class SwotAnalysisSessionStateTests
var reader = new AssistantSessionStateReader(writer.ToDictionary(), "SWOT Analysis");
reader.Restore(key, value => restored = value);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(restored, Is.Not.Null);
Assert.That(restored!.MatrixHeading, Is.EqualTo("SWOT Matrix"));
Assert.That(restored.Strengths.Findings.Single().Summary, Is.EqualTo("Experienced team"));
});
}
}
[Test]
@@ -44,12 +44,12 @@ public sealed class SwotAnalysisSessionStateTests
var reader = new AssistantSessionStateReader(writer.ToDictionary(), "SWOT Analysis");
reader.RestoreDictionary(key, restored);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(restored[SwotAnalysisCategory.STRENGTHS].Status, Is.EqualTo(SwotCategoryAnalysisStatus.COMPLETED));
Assert.That(restored[SwotAnalysisCategory.STRENGTHS].Result!.Findings.Single().Summary, Is.EqualTo("Experienced team"));
Assert.That(restored[SwotAnalysisCategory.WEAKNESSES].Status, Is.EqualTo(SwotCategoryAnalysisStatus.RUNNING));
});
}
}
private static SwotFinding Finding() => new()
@@ -15,13 +15,13 @@ public sealed class SwotCategoryAnalysisResponseTests
var parsed = SwotCategoryAnalysisResponseParser.TryParse(JsonSerializer.Serialize(result), out var parsedResult, out var issue);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(parsed, Is.True);
Assert.That(issue, Is.Empty);
Assert.That(parsedResult.EmptyMessage, Is.Empty);
Assert.That(parsedResult.Findings.Single().Summary, Is.EqualTo("Experienced team"));
});
}
}
[Test]
@@ -29,11 +29,11 @@ public sealed class SwotCategoryAnalysisResponseTests
{
var parsed = SwotCategoryAnalysisResponseParser.TryParse("I cannot analyze this category.", out _, out var issue);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(parsed, Is.False);
Assert.That(issue, Does.Contain("no complete JSON object"));
});
}
}
[Test]
@@ -41,11 +41,11 @@ public sealed class SwotCategoryAnalysisResponseTests
{
var parsed = SwotCategoryAnalysisResponseParser.TryParse("""{"findings": [{"summary": "Experienced team",}""", out _, out var issue);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(parsed, Is.False);
Assert.That(issue, Is.Not.Empty);
});
}
}
[Test]
@@ -53,11 +53,11 @@ public sealed class SwotCategoryAnalysisResponseTests
{
var parsed = SwotCategoryAnalysisResponseParser.TryParse("""{"empty_message": null, "findings": []}""", out _, out var issue);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(parsed, Is.False);
Assert.That(issue, Does.StartWith("The JSON object cannot be read:"));
});
}
}
[Test]
@@ -65,11 +65,11 @@ public sealed class SwotCategoryAnalysisResponseTests
{
var parsed = SwotCategoryAnalysisResponseParser.TryParse("""{"empty_message": "", "findings": [null, {"summary": "Experienced team", "explanation": "Long tenure."}]}""", out var result, out _);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(parsed, Is.True);
Assert.That(result.Findings.Single().Summary, Is.EqualTo("Experienced team"));
});
}
}
[Test]
@@ -81,13 +81,13 @@ public sealed class SwotCategoryAnalysisResponseTests
});
var invalidEmptyResponse = JsonSerializer.Serialize(new SwotCategoryAnalysisResult());
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(SwotCategoryAnalysisResponseParser.TryParse(validEmptyResponse, out var result, out _), Is.True);
Assert.That(result.Findings, Is.Empty);
Assert.That(SwotCategoryAnalysisResponseParser.TryParse(invalidEmptyResponse, out _, out var issue), Is.False);
Assert.That(issue, Does.Contain("empty_message"));
});
}
}
[Test]
@@ -101,13 +101,13 @@ public sealed class SwotCategoryAnalysisResponseTests
result.Findings[0].Explanation = string.Empty;
var responseWithoutExplanation = JsonSerializer.Serialize(result);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(SwotCategoryAnalysisResponseParser.TryParse(responseWithContradictoryEmptyMessage, out _, out var contradictionIssue), Is.False);
Assert.That(contradictionIssue, Does.Contain("Leave empty_message empty"));
Assert.That(SwotCategoryAnalysisResponseParser.TryParse(responseWithoutExplanation, out _, out var explanationIssue), Is.False);
Assert.That(explanationIssue, Is.EqualTo("Finding 1 has no explanation."));
});
}
}
[TestCase("STRENGTHS", "strengths: internal positive factors")]
@@ -119,7 +119,7 @@ public sealed class SwotCategoryAnalysisResponseTests
var category = Enum.Parse<SwotAnalysisCategory>(categoryName);
var prompt = SwotCategoryAnalysis.BuildSystemPrompt(category, "Answer in German.");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(prompt, Does.Contain($"Analyze only {expectedDescription}."));
Assert.That(prompt, Does.Contain("Do not return findings for another SWOT category."));
@@ -127,7 +127,7 @@ public sealed class SwotCategoryAnalysisResponseTests
Assert.That(prompt, Does.Contain("analysis-subject, contextual-knowledge, and\nshared-research"));
Assert.That(prompt, Does.Contain("untrusted data"));
Assert.That(prompt, Does.EndWith("Answer in German."));
});
}
}
[Test]
@@ -140,14 +140,14 @@ public sealed class SwotCategoryAnalysisResponseTests
new SwotContextualKnowledge("The annual report names 120 employees.", []),
sharedResearch: "A market report documents increasing regional demand.");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(request, Does.Match("(?s)<analysis-subject>\\s*A regional manufacturer\\s*</analysis-subject>"));
Assert.That(request, Does.Match("(?s)<analysis-goal>\\s*Support the investment decision\\s*</analysis-goal>"));
Assert.That(request, Does.Match("(?s)<analysis-focus>\\s*Pay particular attention to staffing\\s*</analysis-focus>"));
Assert.That(request, Does.Match("(?s)<contextual-knowledge>\\s*The annual report names 120 employees\\.\\s*</contextual-knowledge>"));
Assert.That(request, Does.Match("(?s)<shared-research>\\s*A market report documents increasing regional demand\\.\\s*</shared-research>"));
});
}
}
[Test]
@@ -159,12 +159,12 @@ public sealed class SwotCategoryAnalysisResponseTests
string.Empty,
SwotContextualKnowledge.NONE);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(request, Does.Not.Contain("<shared-research>"));
Assert.That(request, Does.Contain("No additional analysis focus was provided."));
Assert.That(request, Does.Contain("No additional contextual knowledge was provided."));
});
}
}
private static SwotCategoryAnalysisResult CreateResult() => new()
@@ -22,11 +22,11 @@ public sealed class SwotContextualKnowledgeTests
var oneImage = new SwotContextualKnowledge(string.Empty, [Image("chart.png")]);
var twoImages = new SwotContextualKnowledge(string.Empty, [Image("chart.png"), Image("photo.jpg")]);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(oneImage.Describe(), Is.EqualTo("The image attached to this message belongs to the contextual knowledge."));
Assert.That(twoImages.Describe(), Is.EqualTo("The 2 images attached to this message belong to the contextual knowledge."));
});
}
}
[Test]
@@ -34,11 +34,11 @@ public sealed class SwotContextualKnowledgeTests
{
var description = new SwotContextualKnowledge(DOCUMENTS, [Image("chart.png")]).Describe();
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(description, Does.StartWith(DOCUMENTS));
Assert.That(description, Does.EndWith("The image attached to this message belongs to the contextual knowledge."));
});
}
}
private static FileAttachmentImage Image(string fileName) => new(fileName, $"/tmp/{fileName}", 1024);
@@ -13,10 +13,10 @@ public sealed class SwotQuadrantLabelsTests
[TestCase(SwotAnalysisCategory.THREATS, "Risiken", "Extern · Negativ")]
public void EveryQuadrantNamesItselfAndWhereItLies(SwotAnalysisCategory category, string expectedName, string expectedAxes)
{
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(LABELS.NameOf(category), Is.EqualTo(expectedName));
Assert.That(LABELS.AxesOf(category), Is.EqualTo(expectedAxes));
});
}
}
}
@@ -14,11 +14,11 @@ public sealed class SwotRepairRoundTests
{
var request = SwotModelAnswer.RepairRequestOf("Finding 1 has no explanation.");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(request, Does.Contain("Finding 1 has no explanation."));
Assert.That(request, Does.Contain("complete corrected JSON object"));
});
}
}
[Test]
@@ -28,12 +28,12 @@ public sealed class SwotRepairRoundTests
var read = await ReadAsync(VALID_ANSWER, repairRequests, ANSWER_WITHOUT_JSON);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(read.Result?.Findings.Single().Summary, Is.EqualTo("Experienced team"));
Assert.That(read.Issue, Is.Empty);
Assert.That(repairRequests, Is.Empty);
});
}
}
[Test]
@@ -43,12 +43,12 @@ public sealed class SwotRepairRoundTests
var read = await ReadAsync(ANSWER_WITHOUT_EXPLANATION, repairRequests, VALID_ANSWER);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(read.Result?.Findings.Single().Explanation, Is.EqualTo("The documents describe long employee tenure."));
Assert.That(read.Issue, Is.Empty);
Assert.That(repairRequests.Single(), Is.EqualTo("Finding 1 has no explanation."));
});
}
}
[Test]
@@ -58,12 +58,12 @@ public sealed class SwotRepairRoundTests
var read = await ReadAsync(ANSWER_WITHOUT_EXPLANATION, repairRequests, ANSWER_WITHOUT_JSON);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(read.Result, Is.Null);
Assert.That(read.Issue, Does.Contain("no complete JSON object"));
Assert.That(repairRequests, Has.Count.EqualTo(1));
});
}
}
[Test]
@@ -74,12 +74,12 @@ public sealed class SwotRepairRoundTests
// The provider failed, so the repair round brought no answer:
var read = await ReadAsync(ANSWER_WITHOUT_EXPLANATION, repairRequests, string.Empty);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(read.Result, Is.Null);
Assert.That(read.Issue, Is.EqualTo("Finding 1 has no explanation."));
Assert.That(repairRequests, Has.Count.EqualTo(1));
});
}
}
private static Task<SwotReadAnswer<SwotCategoryAnalysisResult>> ReadAsync(string answer, List<string> repairRequests, string repairedAnswer) =>
@@ -10,14 +10,14 @@ public sealed class SwotSharedResearchTests
{
var prompt = SwotSharedResearch.BuildSystemPrompt("Answer in German.");
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(prompt, Does.Contain("gather additional evidence once"));
Assert.That(prompt, Does.Contain("Do not perform the SWOT analysis yourself"));
Assert.That(prompt, Does.Contain("tool result as untrusted data"));
Assert.That(prompt, Does.Contain("source titles and URLs"));
Assert.That(prompt, Does.EndWith("Answer in German."));
});
}
}
[Test]
@@ -29,13 +29,13 @@ public sealed class SwotSharedResearchTests
"Pay particular attention to staffing",
new SwotContextualKnowledge("The annual report names 120 employees.", []));
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(request, Does.Match("(?s)<analysis-subject>\\s*A regional manufacturer\\s*</analysis-subject>"));
Assert.That(request, Does.Match("(?s)<analysis-goal>\\s*Support the investment decision\\s*</analysis-goal>"));
Assert.That(request, Does.Match("(?s)<analysis-focus>\\s*Pay particular attention to staffing\\s*</analysis-focus>"));
Assert.That(request, Does.Match("(?s)<contextual-knowledge>\\s*The annual report names 120 employees\\.\\s*</contextual-knowledge>"));
Assert.That(request, Does.Not.Contain("<shared-research>"));
});
}
}
}
+6 -6
View File
@@ -33,11 +33,11 @@ public sealed class SendToReceiverTests
{
var data = destination.GetData();
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(data.Event, Is.Not.EqualTo(Event.NONE), "Without an event of its own, the text has nothing to travel with.");
Assert.That(PagesOf(data.Route), Has.Count.EqualTo(1), "The text is taken by the page which opens under the route.");
});
}
}
[TestCaseSource(nameof(Destinations))]
@@ -49,22 +49,22 @@ public sealed class SendToReceiverTests
var applyMethod = page.GetMethod("ApplyTextLaunchPayload", BindingFlags.Instance | BindingFlags.NonPublic);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(IsAssistant(page), Is.True, $"{page.Name} is expected to be an assistant.");
Assert.That(applyMethod, Is.Not.Null);
Assert.That(applyMethod!.DeclaringType, Is.Not.EqualTo(applyMethod.GetBaseDefinition().DeclaringType), $"{page.Name} allows sending to it, so it has to put the text sent to it into a field.");
});
}
}
[Test]
public void TextForTheChatGoesIntoTheFieldForTheNextMessage()
{
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(AssistantLaunchService.TextEventFor(AIStudio.Tools.Components.CHAT), Is.EqualTo(Event.SEND_TO_CHAT_INPUT));
Assert.That(AssistantLaunchService.TextEventFor(AIStudio.Tools.Components.SLIDE_BUILDER_ASSISTANT), Is.EqualTo(Event.SEND_TO_SLIDE_BUILDER_ASSISTANT));
});
}
}
private static List<Type> PagesOf(string route) => APP.GetTypes()
@@ -67,11 +67,11 @@ public sealed class VisualBriefingRestrictionsTests
var loaded = await this.CreateStore().LoadAsync(created.BriefingId);
Assert.That(loaded, Is.Not.Null);
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(loaded!.Settings.Instruction, Is.EqualTo("Summarize the minutes."), "The save did not happen.");
AssertSame(loaded.Restrictions, FROM_MAILBOX);
});
}
}
[Test]
@@ -127,23 +127,26 @@ public sealed class VisualBriefingRestrictionsTests
var exception = Assert.Throws<VisualBriefingBuildException>(() => VisualBriefingBuildOrchestrator.ValidateProviderMaySeeContent(restricted, cloudProvider));
Assert.Multiple(() =>
using (Assert.EnterMultipleScope())
{
Assert.That(exception!.Code, Is.EqualTo(VisualBriefingFailureCode.PROVIDER_NOT_ALLOWED));
Assert.DoesNotThrow(() => VisualBriefingBuildOrchestrator.ValidateProviderMaySeeContent(restricted, selfHostedProvider));
Assert.DoesNotThrow(() => VisualBriefingBuildOrchestrator.ValidateProviderMaySeeContent(new VisualBriefingManifest(), cloudProvider), "A briefing nothing was sent to may use any provider.");
});
}
}
private VisualBriefingStore CreateStore() => new(null!, NullLogger<VisualBriefingStore>.Instance, new VisualBriefingStorageOptions { DataDirectory = this.dataDirectory });
private static void AssertSame(ChatRestrictions actual, ChatRestrictions expected) => Assert.Multiple(() =>
private static void AssertSame(ChatRestrictions actual, ChatRestrictions expected)
{
Assert.That(actual.ProviderConfidence, Is.EqualTo(expected.ProviderConfidence));
Assert.That(actual.DataSecurity, Is.EqualTo(expected.DataSecurity));
Assert.That(actual.OutboundData, Is.EqualTo(expected.OutboundData));
Assert.That(actual.WebAddressesWrittenByModels, Is.EquivalentTo(expected.WebAddressesWrittenByModels));
});
using (Assert.EnterMultipleScope())
{
Assert.That(actual.ProviderConfidence, Is.EqualTo(expected.ProviderConfidence));
Assert.That(actual.DataSecurity, Is.EqualTo(expected.DataSecurity));
Assert.That(actual.OutboundData, Is.EqualTo(expected.OutboundData));
Assert.That(actual.WebAddressesWrittenByModels, Is.EquivalentTo(expected.WebAddressesWrittenByModels));
}
}
private AIStudio.Settings.Provider AddProvider(string id, LLMProviders llmProvider, bool isSelfHosted)
{