mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-11 19:36:28 +00:00
Tests - Add Artemis.Core and profile editor test suites (#907)
This commit is contained in:
1 parent
6e7fae16d2
commit
504845c7d2
168 files changed
+22914
-7
No files matched your search
@@ -0,0 +1,191 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using Artemis.Core.Tests.Infrastructure.Storage;
|
||||
using Artemis.Storage.Entities.Profile;
|
||||
using Artemis.Storage.Entities.Profile.AdaptionHints;
|
||||
using Artemis.Storage.Entities.Profile.Conditions;
|
||||
using Artemis.Storage.Migrations.Profile;
|
||||
|
||||
namespace Artemis.Core.Tests.Storage.Migrations;
|
||||
|
||||
public class M0003SystemTextJsonTests
|
||||
{
|
||||
private readonly M0003SystemTextJson _migration = new();
|
||||
|
||||
[Fact]
|
||||
public void Version_IsThree()
|
||||
{
|
||||
_migration.Version.ShouldBe(3);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Migrate_ConvertsEverythingButNodeStorage()
|
||||
{
|
||||
(JsonObject configuration, JsonObject profile) = Version2Profile();
|
||||
|
||||
_migration.Migrate(configuration, profile);
|
||||
|
||||
// Node storage is a JSON string inside the JSON and is left for M0004, copy what M0004 makes of it
|
||||
CopyNodeStorage(OldProfileJson.MigratedConfiguration, configuration);
|
||||
CopyNodeStorage(OldProfileJson.MigratedProfile, profile);
|
||||
// Only MigrateProfile sets the version
|
||||
configuration["Version"] = 4;
|
||||
configuration.ShouldBeJson(OldProfileJson.MigratedConfiguration);
|
||||
profile.ShouldBeJson(OldProfileJson.MigratedProfile);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Migrate_LeavesNodeStorageAlone()
|
||||
{
|
||||
(JsonObject configuration, JsonObject profile) = Version2Profile();
|
||||
|
||||
_migration.Migrate(configuration, profile);
|
||||
|
||||
configuration.FindNode(OldProfileJson.ActivationDataModelNodeId)["Storage"]!.GetValue<string>()
|
||||
.ShouldStartWith("{\"$type\":\"Artemis.Storage.Entities.Profile.DataModelPathEntity, Artemis.Storage\"");
|
||||
profile.FindNode(OldProfileJson.LayerBrushNodeId)["Storage"]!.GetValue<string>()
|
||||
.ShouldStartWith("{\"$type\":\"Artemis.Core.ColorGradient, Artemis.Core\",\"$values\":[");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Migrate_ProfileCanBeReadAfterwards()
|
||||
{
|
||||
(JsonObject configuration, JsonObject profile) = Version2Profile();
|
||||
|
||||
_migration.Migrate(configuration, profile);
|
||||
|
||||
ProfileEntity entity = profile.Deserialize<ProfileEntity>(Constants.JsonConvertSettings)!;
|
||||
entity.Folders.ShouldHaveSingleItem().DisplayCondition.ShouldBeOfType<StaticConditionEntity>();
|
||||
LayerEntity layer = entity.Layers.ShouldHaveSingleItem();
|
||||
layer.DisplayCondition.ShouldBeOfType<EventConditionEntity>();
|
||||
layer.AdaptionHints.Count.ShouldBe(2);
|
||||
layer.AdaptionHints[0].ShouldBeOfType<CategoryAdaptionHintEntity>();
|
||||
layer.AdaptionHints[1].ShouldBeOfType<KeyboardSectionAdaptionHintEntity>();
|
||||
layer.Leds.Count.ShouldBe(2);
|
||||
|
||||
ProfileConfigurationEntity configurationEntity = configuration.Deserialize<ProfileConfigurationEntity>(Constants.JsonConvertSettings)!;
|
||||
configurationEntity.ActivationCondition!.Nodes.Count.ShouldBe(2);
|
||||
configurationEntity.EnableHotkey!.Key.ShouldBe(44);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Artemis.Storage.Entities.Profile.AdaptionHints.CategoryAdaptionHintEntity, Artemis.Storage", "Category")]
|
||||
[InlineData("Artemis.Storage.Entities.Profile.AdaptionHints.DeviceAdaptionHintEntity, Artemis.Storage", "Device")]
|
||||
[InlineData("Artemis.Storage.Entities.Profile.AdaptionHints.KeyboardSectionAdaptionHintEntity, Artemis.Storage", "KeyboardSection")]
|
||||
[InlineData("Artemis.Storage.Entities.Profile.AdaptionHints.SingleLedAdaptionHintEntity, Artemis.Storage", "SingleLed")]
|
||||
[InlineData("Artemis.Storage.Entities.Profile.Conditions.AlwaysOnConditionEntity, Artemis.Storage", "AlwaysOn")]
|
||||
[InlineData("Artemis.Storage.Entities.Profile.Conditions.EventConditionEntity, Artemis.Storage", "Event")]
|
||||
[InlineData("Artemis.Storage.Entities.Profile.Conditions.PlayOnceConditionEntity, Artemis.Storage", "PlayOnce")]
|
||||
[InlineData("Artemis.Storage.Entities.Profile.Conditions.StaticConditionEntity, Artemis.Storage", "Static")]
|
||||
public void Migrate_GivesAdaptionHintsAndConditionsTheirShortTypeName(string oldType, string newType)
|
||||
{
|
||||
JsonObject profile = new() {["Element"] = new JsonObject {["$type"] = oldType, ["Value"] = 1}};
|
||||
|
||||
_migration.Migrate(new JsonObject(), profile);
|
||||
|
||||
profile.ShouldBeJson($$$"""{"Element": {"$type": "{{{newType}}}", "Value": 1}}""");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Artemis.Storage.Entities.Profile.LayerEntity, Artemis.Storage")]
|
||||
[InlineData("Artemis.Storage.Entities.Profile.Conditions.SomeNewConditionEntity, Artemis.Storage")]
|
||||
[InlineData("Static")]
|
||||
public void Migrate_RemovesAnyOtherTypeName(string type)
|
||||
{
|
||||
JsonObject profile = new() {["$type"] = type, ["Element"] = new JsonObject {["$type"] = type, ["Value"] = 1}};
|
||||
|
||||
_migration.Migrate(new JsonObject(), profile);
|
||||
|
||||
profile.ShouldBeJson("""{"Element": {"Value": 1}}""");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Migrate_ReplacesListsByTheirValues_WhateverTheirType()
|
||||
{
|
||||
JsonObject profile = OldProfileJson.Parse("""
|
||||
{
|
||||
"Numbers": {"$type": "System.Int32[], System.Private.CoreLib", "$values": [1, 2]},
|
||||
"Elements": {"$type": "Something else entirely", "$values": [{"$type": "Element", "Children": {"$type": "List", "$values": []}}]}
|
||||
}
|
||||
""");
|
||||
|
||||
_migration.Migrate(new JsonObject(), profile);
|
||||
|
||||
profile.ShouldBeJson("""{"Numbers": [1, 2], "Elements": [{"Children": []}]}""");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Migrate_ListDirectlyInsideAList_KeepsItsValuesWrapper()
|
||||
{
|
||||
JsonObject profile = OldProfileJson.Parse("""
|
||||
{"Rows": {"$type": "List", "$values": [{"$type": "List", "$values": [1, 2]}]}}
|
||||
""");
|
||||
|
||||
_migration.Migrate(new JsonObject(), profile);
|
||||
|
||||
// Pinned as-is: items of a list are only searched for lists in their properties, a list that is itself an item
|
||||
// keeps its "$values" wrapper. No profile entity has a list of lists, so old profiles aren't affected.
|
||||
profile.ShouldBeJson("""{"Rows": [{"$values": [1, 2]}]}""");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Migrate_LeavesObjectsInPlainArraysAlone()
|
||||
{
|
||||
// JSON.NET wrapped every list when it wrote type names, so old profiles have no plain arrays
|
||||
const string json = """{"Elements": [{"$type": "Element", "Children": {"$type": "List", "$values": []}}]}""";
|
||||
JsonObject profile = OldProfileJson.Parse(json);
|
||||
|
||||
_migration.Migrate(new JsonObject(), profile);
|
||||
|
||||
profile.ShouldBeJson(json);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Migrate_ValuesThatAreNull_AreTreatedAsAnObject()
|
||||
{
|
||||
JsonObject profile = OldProfileJson.Parse("""{"Elements": {"$type": "List", "$values": null}}""");
|
||||
|
||||
_migration.Migrate(new JsonObject(), profile);
|
||||
|
||||
profile.ShouldBeJson("""{"Elements": {"$values": null}}""");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Migrate_ValuesThatAreNotAList_Throws()
|
||||
{
|
||||
JsonObject profile = OldProfileJson.Parse("""{"Elements": {"$type": "List", "$values": 5}}""");
|
||||
|
||||
Should.Throw<InvalidOperationException>(() => _migration.Migrate(new JsonObject(), profile));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Migrate_RunningItOnAMigratedProfile_ChangesNothing()
|
||||
{
|
||||
JsonObject configuration = OldProfileJson.Parse(OldProfileJson.MigratedConfiguration);
|
||||
JsonObject profile = OldProfileJson.Parse(OldProfileJson.MigratedProfile);
|
||||
|
||||
_migration.Migrate(configuration, profile);
|
||||
|
||||
// The short type names would be removed (see Migrate_RemovesAnyOtherTypeName), but in a migrated profile they
|
||||
// are all inside plain arrays, which this migration doesn't look into
|
||||
configuration.ShouldBeJson(OldProfileJson.MigratedConfiguration);
|
||||
profile.ShouldBeJson(OldProfileJson.MigratedProfile);
|
||||
profile.FindTypeNames().ShouldBe(["Static", "Category", "KeyboardSection", "Event"]);
|
||||
}
|
||||
|
||||
private (JsonObject Configuration, JsonObject Profile) Version2Profile()
|
||||
{
|
||||
JsonObject configuration = OldProfileJson.Parse(OldProfileJson.Version0Configuration);
|
||||
JsonObject profile = OldProfileJson.Parse(OldProfileJson.Version0Profile);
|
||||
new M0001NodeProviders().Migrate(configuration, profile);
|
||||
new M0002NodeProvidersProfileConfig().Migrate(configuration, profile);
|
||||
return (configuration, profile);
|
||||
}
|
||||
|
||||
private static void CopyNodeStorage(string fromJson, JsonNode to)
|
||||
{
|
||||
JsonNode from = JsonNode.Parse(fromJson)!;
|
||||
foreach (JsonObject node in to.FindNodes())
|
||||
node["Storage"] = from.FindNode(node["Id"]!.GetValue<string>())["Storage"]!.DeepClone();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user