using System.Globalization;
using AIStudio.Assistants.BeyondFactsLab;
using AIStudio.Settings.DataModel;
namespace AIStudio.Tests.BeyondFactsLab;
///
/// Checks how the card sort of the BeyondFacts Lab reaches the chat of its step: as part of the details, with every
/// value of the deck, and never in the chats of the other steps.
///
[TestFixture]
public sealed class BflCardSortPromptTests
{
private const string CORE = "{{DETAILS}}";
private static readonly BflPromptParts PARTS = new(CORE, "Leitfaden", "Schritt", "Anrede", string.Empty);
[Test]
public async Task TheCardSortReachesOnlyTheChatOfItsOwnStep()
{
var deck = await EnglishDeckAsync();
var values = new BflStepFormData { CardSort = new() };
values.CardSort.Sort("honesty", BflValueCategory.ESPECIALLY_IMPORTANT);
values.Set(BflFieldCatalog.VALUES_AND_CONCERNS, "Offenheit");
var forms = new Dictionary { [BflStep.VALUES_AND_PERSPECTIVES] = values };
foreach (var step in BflStep.All)
{
var prompt = BflPromptComposer.Compose(PARTS, step, forms, [], "Deutsch", valueDeck: deck);
using (Assert.EnterMultipleScope())
{
Assert.That(prompt.Contains("Werte-Sortierung", StringComparison.Ordinal), Is.EqualTo(step is BflStep.VALUES_AND_PERSPECTIVES), step.ToString());
Assert.That(prompt, Does.Contain("Offenheit"), "The other details of the step reach every chat, as before.");
}
}
}
[Test]
public async Task TheChatSeesEveryValueWithItsCategoryAndTheSource()
{
var deck = await EnglishDeckAsync();
var values = new BflStepFormData { CardSort = new() };
values.CardSort.Sort("honesty", BflValueCategory.ESPECIALLY_IMPORTANT);
values.CardSort.Sort("progress", BflValueCategory.LESS_IMPORTANT);
var prompt = Compose(values, deck);
using (Assert.EnterMultipleScope())
{
Assert.That(prompt, Does.Contain("- Werte-Sortierung nach Miller, W. R., C’de Baca, J., Matthews, D. B., & Wilbourne, P. L. (2001). Personal Values Card Sort. University of New Mexico:"));
Assert.That(prompt, Does.Contain("\n - Runde 1:\n - Honesty (Present statements sincerely): Especially important\n"));
Assert.That(prompt, Does.Contain($" - Safety (Avoid harm): {BflValueCategory.NONE.Title}\n"));
Assert.That(prompt, Does.Contain($" - Progress (Develop new things and make improvements possible): {BflValueCategory.LESS_IMPORTANT.Title}\n"));
Assert.That(prompt, Does.Contain("\n - Runde 3:"));
foreach (var card in deck.Cards)
Assert.That(prompt, Does.Contain($" - {card.Name} ({card.Definition}): "), card.Id);
}
}
[Test]
public async Task TheChatSeesTheOwnValuesAndTheValuesToLookAtMoreClosely()
{
var deck = await EnglishDeckAsync();
var values = new BflStepFormData { CardSort = new() };
var curiosity = values.CardSort.AddOwnValue("Curiosity", "Ask questions")!;
values.CardSort.AddOwnValue("Patience", string.Empty);
values.CardSort.ChooseFocus(["honesty", curiosity.Id]);
var prompt = Compose(values, deck);
using (Assert.EnterMultipleScope())
{
Assert.That(prompt, Does.Contain(" - Eigene Werte der Person:\n - Curiosity (Ask questions)\n - Patience (ohne Erläuterung)\n"));
Assert.That(prompt, Does.Contain(" - Genauer betrachten möchte die Person: Honesty, Curiosity"));
}
}
[Test]
public async Task WithoutAnySortingTheChatStillSeesTheDeckToOfferIt()
{
var deck = await EnglishDeckAsync();
var prompt = Compose(new BflStepFormData(), deck);
using (Assert.EnterMultipleScope())
{
Assert.That(prompt, Does.Contain($" - Honesty (Present statements sincerely): {BflValueCategory.NONE.Title}"));
Assert.That(prompt, Does.Contain(" - Eigene Werte der Person: keine"));
Assert.That(prompt, Does.Contain(" - Genauer betrachten möchte die Person: noch keine Auswahl"));
}
}
[Test]
public async Task AValueTheDeckDoesNotKnowStaysOut()
{
var deck = await EnglishDeckAsync();
var values = new BflStepFormData { CardSort = new() { Focus = ["value_of_another_deck"] } };
values.CardSort.Sort("value_of_another_deck", BflValueCategory.ESPECIALLY_IMPORTANT);
var prompt = Compose(values, deck);
using (Assert.EnterMultipleScope())
{
Assert.That(prompt, Does.Not.Contain("value_of_another_deck"));
Assert.That(prompt, Does.Contain("noch keine Auswahl"));
}
}
[Test]
public void WithoutADeckThePromptLeavesTheCardSortOut()
{
var values = new BflStepFormData { CardSort = new() };
values.CardSort.Sort("honesty", BflValueCategory.ESPECIALLY_IMPORTANT);
var prompt = BflPromptComposer.Compose(PARTS, BflStep.VALUES_AND_PERSPECTIVES, new Dictionary { [BflStep.VALUES_AND_PERSPECTIVES] = values }, [], "Deutsch");
Assert.That(prompt, Does.Not.Contain("Werte-Sortierung"));
}
[Test]
public async Task ThePromptOfTheStepLeavesTheValuesToTheDeck()
{
var step = await BflPromptLibrary.ReadBuiltInAsync(BflPromptLibrary.StepPath(BflStep.VALUES_AND_PERSPECTIVES));
var deck = await BflValueDeck.LoadAsync(CultureInfo.GetCultureInfo("de"));
using (Assert.EnterMultipleScope())
{
foreach (var card in deck.Cards)
Assert.That(step, Does.Not.Contain(card.Definition).IgnoreCase, $"The prompt of the step repeats the value '{card.Id}' of the deck.");
Assert.That(step, Does.Contain("Werte-Sortierung"));
}
}
[Test]
public async Task TheRealPromptOfTheStepCarriesTheCardSort()
{
var deck = await BflValueDeck.LoadAsync(CultureInfo.GetCultureInfo("de"));
var parts = await BflPromptLibrary.LoadPartsAsync(BflStep.VALUES_AND_PERSPECTIVES, AddressForm.FORMAL);
var values = new BflStepFormData { CardSort = new() };
values.CardSort.Sort("honesty", BflValueCategory.ESPECIALLY_IMPORTANT);
var prompt = BflPromptComposer.Compose(parts, BflStep.VALUES_AND_PERSPECTIVES, new Dictionary { [BflStep.VALUES_AND_PERSPECTIVES] = values }, [], "Deutsch", valueDeck: deck);
Assert.That(prompt, Does.Contain(" - Ehrlichkeit (Aussagen aufrichtig darstellen): "));
}
private static string Compose(BflStepFormData values, BflValueDeck deck) => BflPromptComposer.Compose(PARTS, BflStep.VALUES_AND_PERSPECTIVES, new Dictionary { [BflStep.VALUES_AND_PERSPECTIVES] = values }, [], "Deutsch", valueDeck: deck);
private static Task EnglishDeckAsync() => BflValueDeck.LoadAsync(CultureInfo.GetCultureInfo("en"));
}