175 lines
6.2 KiB
C#
175 lines
6.2 KiB
C#
using Core.Calculation;
|
|
using Core.Entities;
|
|
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}");
|
|
}
|
|
} |