Files
chapter-organizer/Tests/Calculation/EventAssignmentTests.cs
T
poprhythm 45edcf5e5f Refactor event assignment structure and introduce new models for assignment parameters and requirements
This commit removes the obsolete EventAssignment class from Core.Entities and introduces new models in Core.Models, including AssignmentParameters, AssignmentRequirement, PartialTeam, and StudentEventStatistics. The changes enhance the organization of assignment-related data and improve the overall structure of the codebase. Additionally, several files have been updated to include references to the new Core.Models namespace, ensuring consistency across the application.
2026-01-10 18:36:52 -05:00

176 lines
6.2 KiB
C#

using Core.Calculation;
using Core.Entities;
using Core.Models;
using Tests.Builders;
using Tests.Fixtures;
using EventAssignment = Core.Calculation.EventAssignment;
namespace Tests.Calculation;
[TestFixture]
public class EventAssignmentTests
{
[SetUp]
public void SetUp()
{
BuilderExtensions.ResetAllBuilders();
}
[Test]
public async Task SolutionTest()
{
// Create custom test data with sufficient rankings for EventAssignment
// Need enough events and rankings to satisfy the default parameters:
// - 2-4 events per student
// - 6-8 effort points per student
// - At least 1 regional event
// - At least 1 on-site activity
var flight = EventDefinitionBuilder.Individual("Flight").AsRegionalEvent().Build();
var coding = EventDefinitionBuilder.Individual("Coding").AsRegionalEvent().Build();
var speech = EventDefinitionBuilder.Individual("Prepared Speech").AsOnSite().Build();
var photo = EventDefinitionBuilder.Individual("Digital Photography").Build();
var essays = EventDefinitionBuilder.Individual("Essays on Technology").Build();
var robotics = EventDefinitionBuilder.Team("Robotics", 2, 5).AsRegionalEvent().AsOnSite().Build();
var biotech = EventDefinitionBuilder.Team("Biotechnology", 2, 6).AsRegionalEvent().Build();
var webDesign = EventDefinitionBuilder.Team("Website Design", 3, 6).Build();
var videoGame = EventDefinitionBuilder.Team("Video Game Design", 2, 6).Build();
var engineering = EventDefinitionBuilder.Team("Engineering Design", 3, 6).AsOnSite().Build();
var events = new[] { flight, coding, speech, photo, essays, robotics, biotech, webDesign, videoGame, engineering };
// Create students with diverse rankings (each ranks 7-8 events)
var alice = StudentBuilder.Default()
.WithName("Alice", "A").WithGrade(9)
.WithRanking(flight, 1).WithRanking(robotics, 2).WithRanking(biotech, 3)
.WithRanking(speech, 4).WithRanking(webDesign, 5).WithRanking(coding, 6)
.WithRanking(videoGame, 7)
.Build();
var bob = StudentBuilder.Default()
.WithName("Bob", "B").WithGrade(10)
.WithRanking(coding, 1).WithRanking(engineering, 2).WithRanking(robotics, 3)
.WithRanking(speech, 4).WithRanking(biotech, 5).WithRanking(photo, 6)
.WithRanking(videoGame, 7)
.Build();
var carol = StudentBuilder.Default()
.WithName("Carol", "C").WithGrade(11)
.WithRanking(photo, 1).WithRanking(webDesign, 2).WithRanking(engineering, 3)
.WithRanking(speech, 4).WithRanking(biotech, 5).WithRanking(flight, 6)
.WithRanking(coding, 7)
.Build();
var david = StudentBuilder.Default()
.WithName("David", "D").WithGrade(9)
.WithRanking(essays, 1).WithRanking(robotics, 2).WithRanking(videoGame, 3)
.WithRanking(engineering, 4).WithRanking(speech, 5).WithRanking(coding, 6)
.WithRanking(biotech, 7)
.Build();
var eve = StudentBuilder.Default()
.WithName("Eve", "E").WithGrade(10)
.WithRanking(flight, 1).WithRanking(webDesign, 2).WithRanking(engineering, 3)
.WithRanking(robotics, 4).WithRanking(photo, 5).WithRanking(coding, 6)
.WithRanking(speech, 7)
.Build();
var frank = StudentBuilder.Default()
.WithName("Frank", "F").WithGrade(11)
.WithRanking(coding, 1).WithRanking(biotech, 2).WithRanking(videoGame, 3)
.WithRanking(speech, 4).WithRanking(webDesign, 5).WithRanking(flight, 6)
.WithRanking(robotics, 7)
.Build();
var students = new[] { alice, bob, carol, david, eve, frank };
// Use relaxed parameters for test
var parameters = new AssignmentParameters(
effortLowerBound: 4,
effortUpperBound: 7,
eventsLowerBound: 2,
eventsUpperBound: 4,
requireRegional: false, // Relax for test simplicity
requireOnSite: false // Relax for test simplicity
);
var eventAssignment = new EventAssignment(events, students, parameters);
var solution = await eventAssignment.Solve();
// Verify solution
Assert.That(solution.Teams, Is.Not.Null);
Assert.That(solution.Status, Is.EqualTo("Optimal").Or.EqualTo("Feasible"),
$"Solution should be Optimal or Feasible, but was {solution.Status}");
// Print solution summary for verification
Console.WriteLine($"Solution Status: {solution.Status}");
Console.WriteLine($"Teams Created: {solution.Teams.Length}");
Console.WriteLine($"Students Assigned: {solution.Teams.SelectMany(t => t.Students).Distinct().Count()}");
// Verify each team has valid structure
foreach (var team in solution.Teams)
{
Assert.That(team.Event, Is.Not.Null, $"Team should have an event");
Assert.That(team.Students, Is.Not.Empty, $"Team for {team.Event.Name} should have students");
}
}
[Test]
public async Task SolutionTest_WithMinimalData()
{
// Test with minimal custom data to verify basic functionality
var flight = EventDefinitionBuilder.Individual("Flight").Build();
var coding = EventDefinitionBuilder.Individual("Coding").Build();
var robotics = EventDefinitionBuilder.Team("Robotics", 2, 5).AsRegionalEvent().Build();
var biotech = EventDefinitionBuilder.Team("Biotechnology", 2, 6).AsRegionalEvent().Build();
var events = new[] { flight, coding, robotics, biotech };
var alice = StudentBuilder.Default()
.WithName("Alice", "A")
.WithGrade(9)
.WithRanking(flight, 1)
.WithRanking(robotics, 2)
.WithRanking(biotech, 3)
.Build();
var bob = StudentBuilder.Default()
.WithName("Bob", "B")
.WithGrade(10)
.WithRanking(coding, 1)
.WithRanking(robotics, 2)
.WithRanking(biotech, 3)
.Build();
var carol = StudentBuilder.Default()
.WithName("Carol", "C")
.WithGrade(11)
.WithRanking(flight, 2)
.WithRanking(biotech, 1)
.WithRanking(robotics, 3)
.Build();
var students = new[] { alice, bob, carol };
// Run the event assignment algorithm with minimal data
var parameters = new AssignmentParameters(
effortLowerBound: 2,
effortUpperBound: 4,
eventsLowerBound: 2,
eventsUpperBound: 3,
requireRegional: false,
requireOnSite: false
);
var eventAssignment = new EventAssignment(events, students, parameters);
var solution = await eventAssignment.Solve();
// Verify solution
Assert.That(solution.Status, Is.EqualTo("Optimal").Or.EqualTo("Feasible"));
Assert.That(solution.Teams, Is.Not.Empty, "Should create some teams");
Console.WriteLine($"Minimal Test - Status: {solution.Status}");
Console.WriteLine($"Teams: {solution.Teams.Length}");
}
}