Multi-Platform Package Manager for Stable Diffusion
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 lines
7.3 KiB

using System.Text.Json;
using System.Text.Json.Serialization;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Moq;
using StabilityMatrix.Avalonia.Models;
using StabilityMatrix.Avalonia.ViewModels;
using StabilityMatrix.Avalonia.ViewModels.Base;
#pragma warning disable CS0657 // Not a valid attribute location for this declaration
namespace StabilityMatrix.Tests.Avalonia;
// Example subclass
public class TestLoadableViewModel : LoadableViewModelBase
{
[JsonInclude]
public string? Included { get; set; }
public int Id { get; set; }
[JsonIgnore]
public int Ignored { get; set; }
}
public class TestLoadableViewModelReadOnly : LoadableViewModelBase
{
public int ReadOnly { get; }
public TestLoadableViewModelReadOnly(int readOnly)
{
ReadOnly = readOnly;
}
}
public class TestLoadableViewModelReadOnlyLoadable : LoadableViewModelBase
{
public TestLoadableViewModel ReadOnlyLoadable { get; } = new();
}
public partial class TestLoadableViewModelObservable : LoadableViewModelBase
{
[ObservableProperty]
[property: JsonIgnore]
private string? title;
[ObservableProperty]
private int id;
[RelayCommand]
private void TestCommand()
{
throw new NotImplementedException();
}
}
public class TestLoadableViewModelNestedInterface : LoadableViewModelBase
{
public IJsonLoadableState? NestedState { get; set; }
}
public class TestLoadableViewModelNested : LoadableViewModelBase
{
public TestLoadableViewModel? NestedState { get; set; }
}
[TestClass]
public class LoadableViewModelBaseTests
{
[TestMethod]
public void TestSaveStateToJsonObject_JsonIgnoreAttribute()
{
var vm = new TestLoadableViewModel
{
Included = "abc",
Id = 123,
Ignored = 456,
};
var state = vm.SaveStateToJsonObject();
// [JsonInclude] and not marked property should be serialized.
// Ignored property should be ignored.
Assert.AreEqual(2, state.Count);
Assert.AreEqual("abc", state["Included"].Deserialize<string>());
Assert.AreEqual(123, state["Id"].Deserialize<int>());
}
[TestMethod]
public void TestSaveStateToJsonObject_Observable()
{
// Mvvm ObservableProperty should be serialized.
var vm = new TestLoadableViewModelObservable
{
Title = "abc",
Id = 123,
};
var state = vm.SaveStateToJsonObject();
// Title should be ignored since it has [JsonIgnore]
// Command should be ignored from excluded type rules
// Id should be serialized
Assert.AreEqual(1, state.Count);
Assert.AreEqual(123, state["Id"].Deserialize<int>());
}
[TestMethod]
public void TestSaveStateToJsonObject_IJsonLoadableState()
{
// Properties of type IJsonLoadableState should be serialized by calling their
// SaveStateToJsonObject method.
// Make a mock IJsonLoadableState
var mockState = new Mock<IJsonLoadableState>();
var vm = new TestLoadableViewModelNestedInterface
{
NestedState = mockState.Object
};
// Serialize
var state = vm.SaveStateToJsonObject();
// Check results
Assert.AreEqual(1, state.Count);
// Check that SaveStateToJsonObject was called
mockState.Verify(x => x.SaveStateToJsonObject(), Times.Once);
}
[TestMethod]
public void TestLoadStateFromJsonObject()
{
// Simple round trip save / load
var vm = new TestLoadableViewModel
{
Included = "abc",
Id = 123,
Ignored = 456,
};
var state = vm.SaveStateToJsonObject();
// Create a new instance and load the state
var vm2 = new TestLoadableViewModel();
vm2.LoadStateFromJsonObject(state);
// Check [JsonInclude] and not marked property was loaded
Assert.AreEqual("abc", vm2.Included);
Assert.AreEqual(123, vm2.Id);
// Check ignored property was not loaded
Assert.AreEqual(0, vm2.Ignored);
}
[TestMethod]
public void TestLoadStateFromJsonObject_Nested_DefaultCtor()
{
// Round trip save / load with nested IJsonLoadableState property
var nested = new TestLoadableViewModel
{
Included = "abc",
Id = 123,
Ignored = 456,
};
var vm = new TestLoadableViewModelNested
{
NestedState = nested
};
var state = vm.SaveStateToJsonObject();
// Create a new instance with null NestedState, rely on default ctor
var vm2 = new TestLoadableViewModelNested();
vm2.LoadStateFromJsonObject(state);
// Check nested state was loaded
Assert.IsNotNull(vm2.NestedState);
var loadedNested = (TestLoadableViewModel) vm2.NestedState;
Assert.AreEqual("abc", loadedNested.Included);
Assert.AreEqual(123, loadedNested.Id);
Assert.AreEqual(0, loadedNested.Ignored);
}
[TestMethod]
public void TestLoadStateFromJsonObject_Nested_Existing()
{
// Round trip save / load with nested IJsonLoadableState property
var nested = new TestLoadableViewModel
{
Included = "abc",
Id = 123,
Ignored = 456,
};
var vm = new TestLoadableViewModelNestedInterface
{
NestedState = nested
};
var state = vm.SaveStateToJsonObject();
// Create a new instance with existing NestedState
var vm2 = new TestLoadableViewModelNestedInterface
{
NestedState = new TestLoadableViewModel()
};
vm2.LoadStateFromJsonObject(state);
// Check nested state was loaded
Assert.IsNotNull(vm2.NestedState);
var loadedNested = (TestLoadableViewModel) vm2.NestedState;
Assert.AreEqual("abc", loadedNested.Included);
Assert.AreEqual(123, loadedNested.Id);
Assert.AreEqual(0, loadedNested.Ignored);
}
[TestMethod]
public void TestLoadStateFromJsonObject_ReadOnly()
{
var vm = new TestLoadableViewModelReadOnly(456);
var state = vm.SaveStateToJsonObject();
// Check no properties were serialized
Assert.AreEqual(0, state.Count);
// Create a new instance and load the state
var vm2 = new TestLoadableViewModelReadOnly(123);
vm2.LoadStateFromJsonObject(state);
// Read only property should have been ignored
Assert.AreEqual(123, vm2.ReadOnly);
}
[TestMethod]
public void TestLoadStateFromJsonObject_ReadOnlyLoadable()
{
var vm = new TestLoadableViewModelReadOnlyLoadable
{
ReadOnlyLoadable =
{
Included = "abc-123"
}
};
var state = vm.SaveStateToJsonObject();
// Check readonly loadable property was serialized
Assert.AreEqual(1, state.Count);
Assert.AreEqual("abc-123", state["ReadOnlyLoadable"].Deserialize<TestLoadableViewModel>()!.Included);
}
}