CI / build-test (push) Successful in 1m13s
- 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.
96 lines
3.0 KiB
C#
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
|
|
}
|
|
}
|