Add core content definitions
This commit is contained in:
111
tests/SideScrollerGame.Content.Tests/ContentValidationTests.cs
Normal file
111
tests/SideScrollerGame.Content.Tests/ContentValidationTests.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using SideScrollerGame.Content.Definitions;
|
||||
using SideScrollerGame.Content.Samples;
|
||||
using SideScrollerGame.Content.Validation;
|
||||
|
||||
namespace SideScrollerGame.Content.Tests;
|
||||
|
||||
public class ContentValidationTests
|
||||
{
|
||||
[Fact]
|
||||
public void SampleContent_ValidatesWithoutErrors()
|
||||
{
|
||||
ContentRegistry registry = SampleContent.CreateRegistry();
|
||||
|
||||
ContentValidationResult result = new ContentValidator().Validate(registry);
|
||||
|
||||
Assert.False(result.HasErrors, string.Join(Environment.NewLine, result.Messages.Select(message => message.Message)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Registry_CanLookUpCoreSampleDefinitions()
|
||||
{
|
||||
ContentRegistry registry = SampleContent.CreateRegistry();
|
||||
|
||||
Assert.True(registry.TryGetMission("mission.test", out MissionDefinition? mission));
|
||||
Assert.NotNull(mission);
|
||||
Assert.Equal("Test Mission", mission.DisplayName);
|
||||
Assert.True(registry.TryGetEnemyType("enemy.serial", out EnemyTypeDefinition? enemy));
|
||||
Assert.NotNull(enemy);
|
||||
Assert.Equal(12, enemy.Health);
|
||||
Assert.True(registry.Weapons.ContainsKey("weapon.primary.basic"));
|
||||
Assert.True(registry.TryGetDifficulty("difficulty.normal", out DifficultyDefinition? difficulty));
|
||||
Assert.NotNull(difficulty);
|
||||
Assert.Equal(3, difficulty.HeroStartingShieldCharges);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_DuplicateIds_ReportsDuplicatedId()
|
||||
{
|
||||
ContentRegistry sample = SampleContent.CreateRegistry();
|
||||
ContentRegistry registry = CreateRegistry(sample, difficulties: sample.DifficultyDefinitions.Append(sample.DifficultyDefinitions[0] with { DisplayName = "Duplicate Easy" }).ToList());
|
||||
|
||||
ContentValidationResult result = new ContentValidator().Validate(registry);
|
||||
|
||||
Assert.Contains(result.Messages, message => message.Code == "content.id.duplicate" && message.Message.Contains("difficulty.easy", StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_MissionWithMissingCluster_ReportsMissingCluster()
|
||||
{
|
||||
ContentRegistry sample = SampleContent.CreateRegistry();
|
||||
ContentRegistry registry = CreateRegistry(sample, missions:
|
||||
[
|
||||
sample.MissionDefinitions[0] with { ClusterIds = ["cluster.opening", "cluster.missing"] }
|
||||
]);
|
||||
|
||||
ContentValidationResult result = new ContentValidator().Validate(registry);
|
||||
|
||||
Assert.Contains(result.Messages, message => message.Code == "mission.cluster.missing" && message.DefinitionId == "mission.test" && message.Message.Contains("cluster.missing", StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_ClusterWithMissingEnemyType_ReportsMissingEnemy()
|
||||
{
|
||||
ContentRegistry sample = SampleContent.CreateRegistry();
|
||||
ContentRegistry registry = CreateRegistry(sample, enemyClusters:
|
||||
[
|
||||
sample.EnemyClusterDefinitions[0] with { Spawns = [new SpawnScheduleEntryDefinition("enemy.missing", 1.0, 1.0, 0.5)] }
|
||||
]);
|
||||
|
||||
ContentValidationResult result = new ContentValidator().Validate(registry);
|
||||
|
||||
Assert.Contains(result.Messages, message => message.Code == "cluster.enemy.missing" && message.DefinitionId == "cluster.opening" && message.Message.Contains("enemy.missing", StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_BehaviorTrackWithNoEvents_ReportsBehavior()
|
||||
{
|
||||
ContentRegistry sample = SampleContent.CreateRegistry();
|
||||
ContentRegistry registry = CreateRegistry(sample, enemyBehaviors:
|
||||
[
|
||||
sample.EnemyBehaviorDefinitions[0] with { Tracks = [new BehaviorTrackDefinition("track.empty", BehaviorTrackMode.Serial, [])] },
|
||||
sample.EnemyBehaviorDefinitions[1]
|
||||
]);
|
||||
|
||||
ContentValidationResult result = new ContentValidator().Validate(registry);
|
||||
|
||||
Assert.Contains(result.Messages, message => message.Code == "behavior.track.events.empty" && message.DefinitionId == "behavior.enemy.serial");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_DifficultyWithNonPositiveMultiplier_ReportsDifficulty()
|
||||
{
|
||||
ContentRegistry sample = SampleContent.CreateRegistry();
|
||||
DifficultyDefinition invalidDifficulty = sample.DifficultyDefinitions[1] with { Modifiers = sample.DifficultyDefinitions[1].Modifiers with { EnemyHealthMultiplier = 0.0 } };
|
||||
ContentRegistry registry = CreateRegistry(sample, difficulties:
|
||||
[
|
||||
sample.DifficultyDefinitions[0],
|
||||
invalidDifficulty,
|
||||
sample.DifficultyDefinitions[2]
|
||||
]);
|
||||
|
||||
ContentValidationResult result = new ContentValidator().Validate(registry);
|
||||
|
||||
Assert.Contains(result.Messages, message => message.Code == "difficulty.multiplier.invalid" && message.DefinitionId == "difficulty.normal" && message.Message.Contains("EnemyHealthMultiplier", StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
private static ContentRegistry CreateRegistry(ContentRegistry sample, IReadOnlyList<MissionDefinition>? missions = null, IReadOnlyList<DifficultyDefinition>? difficulties = null, IReadOnlyList<CameraPathDefinition>? cameraPaths = null, IReadOnlyList<LevelLayerDefinition>? levelLayers = null, IReadOnlyList<EnemyTypeDefinition>? enemyTypes = null, IReadOnlyList<EnemyBehaviorDefinition>? enemyBehaviors = null, IReadOnlyList<EnemyClusterDefinition>? enemyClusters = null, IReadOnlyList<CollectibleDefinition>? collectibles = null, IReadOnlyList<WeaponDefinition>? weapons = null, IReadOnlyList<SpecialWeaponDefinition>? specialWeapons = null, IReadOnlyList<SquadronMateTypeDefinition>? squadronMateTypes = null)
|
||||
{
|
||||
return new ContentRegistry(missions ?? sample.MissionDefinitions, difficulties ?? sample.DifficultyDefinitions, cameraPaths ?? sample.CameraPathDefinitions, levelLayers ?? sample.LevelLayerDefinitions, enemyTypes ?? sample.EnemyTypeDefinitions, enemyBehaviors ?? sample.EnemyBehaviorDefinitions, enemyClusters ?? sample.EnemyClusterDefinitions, collectibles ?? sample.CollectibleDefinitions, weapons ?? sample.WeaponDefinitions, specialWeapons ?? sample.SpecialWeaponDefinitions, squadronMateTypes ?? sample.SquadronMateTypeDefinitions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
<GodotProjectDir>$(MSBuildProjectDirectory)\..\..\godot\</GodotProjectDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.4" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||
<PackageReference Include="xunit" Version="2.9.3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
<CompilerVisibleProperty Include="GodotProjectDir" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\godot\SideScrollerGame.Godot.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
9
tests/SideScrollerGame.Content.Tests/UnitTest1.cs
Normal file
9
tests/SideScrollerGame.Content.Tests/UnitTest1.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace SideScrollerGame.Content.Tests;
|
||||
|
||||
public class UnitTest1
|
||||
{
|
||||
[Fact]
|
||||
public void Test1()
|
||||
{
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user