Files
Leonid Pershin 38bdfbbb81
CI / build-test (push) Successful in 1m13s
Enhance Calendar and Climate systems with start day offsets
- Added a `startDay` parameter to the `Calendar` class to allow for fractional day offsets at clock initialization, enabling more flexible time settings.
- Updated `TotalDays` calculation to include the `startDay` offset.
- Introduced `StartDayOfYear` in `ClimateSettings` to shift the seasonal phase, allowing worlds to begin at a specific time of year.
- Adjusted `YearProgress` and `Year` calculations in the `Climate` class to account for the new `StartDayOfYear`.
- Added unit tests to verify the functionality of the new start day features in both `Calendar` and `Climate` classes.
2026-06-13 06:55:09 +03:00

96 lines
3.0 KiB
C#

using MrGameEng.Core;
using Xunit;
namespace MrGameEng.Core.Tests;
public class ClimateTests
{
private static (GameClock Clock, Climate Climate) Make(ClimateSettings settings)
{
var clock = new GameClock();
var calendar = new Calendar(clock, secondsPerDay: 10f);
return (clock, new Climate(calendar, settings));
}
private static ClimateSettings Seasonal =>
new()
{
DaysPerYear = 60,
MeanTemperature = 10f,
SeasonalAmplitude = 20f,
DailyAmplitude = 0f,
WarmestDay = 15,
};
[Fact]
public void Constructor_NonPositiveYear_Throws()
{
Assert.Throws<ArgumentOutOfRangeException>(() =>
new Climate(new Calendar(new GameClock(), 10f), Seasonal with { DaysPerYear = 0 })
);
}
[Fact]
public void Temperature_PeaksOnWarmestDay_AndBottomsHalfYearLater()
{
var (clock, climate) = Make(Seasonal);
clock.Advance(15 * 10f); // day 15 = warmest
Assert.Equal(30f, climate.Temperature, 2); // mean 10 + amplitude 20
clock.Advance(30 * 10f); // +30 days = half a 60-day year later
Assert.Equal(-10f, climate.Temperature, 2); // mean 10 - amplitude 20
}
[Fact]
public void DailySwing_WarmerAtNoonThanMidnight()
{
var settings = Seasonal with { SeasonalAmplitude = 0f, DailyAmplitude = 6f };
var (clock, climate) = Make(settings);
clock.Advance(5f); // day 0, noon (DayProgress 0.5)
Assert.Equal(16f, climate.Temperature, 2); // mean 10 + daily 6
clock.Advance(5f); // day 1, midnight (DayProgress 0)
Assert.Equal(4f, climate.Temperature, 2); // mean 10 - daily 6
}
[Fact]
public void Season_FollowsTheQuarterOfTheYear()
{
var (clock, climate) = Make(Seasonal); // 60-day year → 15 days per season
Assert.Equal(Season.Spring, climate.Season);
clock.Advance(20 * 10f);
Assert.Equal(Season.Summer, climate.Season);
clock.Advance(15 * 10f);
Assert.Equal(Season.Autumn, climate.Season);
clock.Advance(15 * 10f);
Assert.Equal(Season.Winter, climate.Season);
}
[Fact]
public void YearAndDayOfYear_RollOver()
{
var (clock, climate) = Make(Seasonal);
Assert.Equal(1, climate.Year);
Assert.Equal(0, climate.DayOfYear);
clock.Advance(60 * 10f); // exactly one year
Assert.Equal(2, climate.Year);
Assert.Equal(0, climate.DayOfYear);
}
[Fact]
public void StartDayOfYear_ShiftsTheSeasonalPhase()
{
// Begin the world already at the warmest day (15): the curve peaks at clock 0.
var (_, climate) = Make(Seasonal with { StartDayOfYear = 15 });
Assert.Equal(30f, climate.Temperature, 2); // mean 10 + amplitude 20, at the peak
Assert.Equal(15, climate.DayOfYear); // day-of-year reflects the offset
Assert.Equal(Season.Summer, climate.Season); // day 15 of a 60-day year = start of summer
}
}