← All source files

V15 / 313404a015e8

ProjectTestActionConverter.cs

Lilith/Core/Projects/ProjectTestActionConverter.cs

Unchanged from the preceding version
CS
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Lilith.Core.Projects;

// Canonicalize harmless model formatting variants, never infer missing assertions.
public sealed class ProjectTestActionConverter : JsonConverter<ProjectTestAction>
{
    public override ProjectTestAction Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using var document = JsonDocument.ParseValue(ref reader);
        var root = document.RootElement;
        if (root.ValueKind != JsonValueKind.Object) throw new JsonException("Test action must be an object.");
        var properties = new Dictionary<string, JsonElement>(StringComparer.OrdinalIgnoreCase);
        foreach (var property in root.EnumerateObject())
            if (!properties.TryAdd(property.Name, property.Value) || property.Name.ToLowerInvariant() is not ("type" or "selector" or "value" or "expected" or "width" or "height")) throw new JsonException("Unknown/duplicate browser action field: " + property.Name);
        string Text(string key) => properties.TryGetValue(key, out var value) ? value.ValueKind == JsonValueKind.String ? value.GetString()! : throw new JsonException(key + " must be a string.") : "";
        string type = Text("type"), selector = Text("selector"), text = "";
        if (properties.TryGetValue("expected", out var expected))
        {
            if (type != "assert_text" || properties.ContainsKey("value") || expected.ValueKind != JsonValueKind.String) throw new JsonException("expected is an alias for assert_text value only; provide one expected string.");
            text = expected.GetString()!;
        }
        else if (properties.TryGetValue("value", out var value))
            text = type == "wait" && value.ValueKind == JsonValueKind.Number ? value.GetRawText() : Text("value");
        int Number(string key) => !properties.TryGetValue(key, out var value) ? 0 : value.ValueKind == JsonValueKind.Number && value.TryGetInt32(out int number) ? number : throw new JsonException(key + " must be an integer.");
        return new(type, selector, text, Number("width"), Number("height"));
    }
    public override void Write(Utf8JsonWriter writer, ProjectTestAction value, JsonSerializerOptions options)
    {
        writer.WriteStartObject(); writer.WriteString("type", value.Type); writer.WriteString("selector", value.Selector); writer.WriteString("value", value.Value);
        writer.WriteNumber("width", value.Width); writer.WriteNumber("height", value.Height); writer.WriteEndObject();
    }
}