513fa1aa16
Comment/XML-doc changes only: - add summaries to ~10k test methods, fixtures, fakes and helpers (+ <param> on theories, <returns> on async Task methods, <inheritdoc/> on interface implementations the checker can resolve) - strip ~2.6k project-tracking references (WP*, P*-*, row-NN, Task N, #NN, Component-0NN) from comments, keeping the explanatory text; reword false positives in comments only - real docs on fakes implementing BCL/library interfaces (IDisposable, ILogger, IOptionsMonitor, IAsyncLifetime) - reword the last 5 src/ false positives (CWE-1236, failures-1, year-0001, M365) Only non-comment edits: four one-line nested classes split across lines so members can carry docs. Build 0 errors / 0 warnings.
153 lines
7.1 KiB
C#
153 lines
7.1 KiB
C#
using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Shared;
|
|
|
|
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Shared;
|
|
|
|
public class SchemaBuilderModelTests
|
|
{
|
|
// ── Parse ─────────────────────────────────────────────────────────────────
|
|
|
|
/// <summary>Verifies that parsing an empty schema returns the fallback model.</summary>
|
|
[Fact]
|
|
public void Parse_Empty_ReturnsFallback()
|
|
{
|
|
var fallback = SchemaBuilderModel.NewObject();
|
|
Assert.Same(fallback, SchemaBuilderModel.Parse(null, fallback));
|
|
Assert.Same(fallback, SchemaBuilderModel.Parse("", fallback));
|
|
Assert.Same(fallback, SchemaBuilderModel.Parse(" ", fallback));
|
|
}
|
|
|
|
/// <summary>Verifies that parsing a malformed schema returns the fallback model.</summary>
|
|
[Fact]
|
|
public void Parse_Malformed_ReturnsFallback()
|
|
{
|
|
var fallback = SchemaBuilderModel.NewObject();
|
|
Assert.Same(fallback, SchemaBuilderModel.Parse("{not json", fallback));
|
|
Assert.Same(fallback, SchemaBuilderModel.Parse("42", fallback));
|
|
}
|
|
|
|
/// <summary>Verifies that parsing an object schema extracts its properties and required names.</summary>
|
|
[Fact]
|
|
public void Parse_ObjectSchema_ExtractsPropertiesAndRequired()
|
|
{
|
|
const string json = """
|
|
{"type":"object","properties":{
|
|
"id":{"type":"integer"},
|
|
"label":{"type":"string"},
|
|
"active":{"type":"boolean"}
|
|
},"required":["id","active"]}
|
|
""";
|
|
var node = SchemaBuilderModel.Parse(json, SchemaBuilderModel.NewObject());
|
|
|
|
Assert.Equal("object", node.Type);
|
|
Assert.Collection(node.Properties,
|
|
p => { Assert.Equal("id", p.Name); Assert.Equal("integer", p.Schema.Type); Assert.True(p.Required); },
|
|
p => { Assert.Equal("label", p.Name); Assert.Equal("string", p.Schema.Type); Assert.False(p.Required); },
|
|
p => { Assert.Equal("active", p.Name); Assert.Equal("boolean", p.Schema.Type); Assert.True(p.Required); });
|
|
}
|
|
|
|
/// <summary>Verifies that parsing an array of a primitive preserves the item type.</summary>
|
|
[Fact]
|
|
public void Parse_ArrayOfPrimitive_PreservesItemType()
|
|
{
|
|
var node = SchemaBuilderModel.Parse(
|
|
@"{""type"":""array"",""items"":{""type"":""integer""}}",
|
|
SchemaBuilderModel.NewValue());
|
|
|
|
Assert.Equal("array", node.Type);
|
|
Assert.NotNull(node.Items);
|
|
Assert.Equal("integer", node.Items!.Type);
|
|
}
|
|
|
|
/// <summary>Verifies that a legacy flat array is translated to an object schema.</summary>
|
|
[Fact]
|
|
public void Parse_LegacyFlatArray_TranslatedToObjectSchema()
|
|
{
|
|
const string json = """[{"name":"x","type":"Integer"},{"name":"y","type":"String","required":false}]""";
|
|
var node = SchemaBuilderModel.Parse(json, SchemaBuilderModel.NewObject());
|
|
|
|
Assert.Equal("object", node.Type);
|
|
Assert.Collection(node.Properties,
|
|
p => { Assert.Equal("x", p.Name); Assert.Equal("integer", p.Schema.Type); Assert.True(p.Required); },
|
|
p => { Assert.Equal("y", p.Name); Assert.Equal("string", p.Schema.Type); Assert.False(p.Required); });
|
|
}
|
|
|
|
/// <summary>Verifies that parsing nested objects recurses into the children.</summary>
|
|
[Fact]
|
|
public void Parse_NestedObjects_Recurses()
|
|
{
|
|
const string json = """
|
|
{"type":"object","properties":{
|
|
"outer":{"type":"object","properties":{
|
|
"inner":{"type":"integer"}
|
|
},"required":["inner"]}
|
|
}}
|
|
""";
|
|
var node = SchemaBuilderModel.Parse(json, SchemaBuilderModel.NewObject());
|
|
|
|
var outer = Assert.Single(node.Properties);
|
|
Assert.Equal("outer", outer.Name);
|
|
Assert.Equal("object", outer.Schema.Type);
|
|
var inner = Assert.Single(outer.Schema.Properties);
|
|
Assert.Equal("inner", inner.Name);
|
|
Assert.Equal("integer", inner.Schema.Type);
|
|
Assert.True(inner.Required);
|
|
}
|
|
|
|
// ── Serialize ─────────────────────────────────────────────────────────────
|
|
|
|
/// <summary>Verifies that serializing an empty object omits the required list.</summary>
|
|
[Fact]
|
|
public void Serialize_EmptyObject_OmitsRequired()
|
|
{
|
|
var node = new SchemaNode { Type = "object" };
|
|
var json = SchemaBuilderModel.Serialize(node);
|
|
Assert.Equal("""{"type":"object","properties":{}}""", json);
|
|
}
|
|
|
|
/// <summary>Verifies that serializing an object with mixed required properties emits only the required names.</summary>
|
|
[Fact]
|
|
public void Serialize_ObjectWithMixedRequired_EmitsOnlyRequiredNames()
|
|
{
|
|
var node = new SchemaNode { Type = "object" };
|
|
node.Properties.Add(new SchemaProperty { Name = "id", Required = true, Schema = new SchemaNode { Type = "integer" } });
|
|
node.Properties.Add(new SchemaProperty { Name = "label", Required = false, Schema = new SchemaNode { Type = "string" } });
|
|
|
|
var json = SchemaBuilderModel.Serialize(node);
|
|
Assert.Equal(
|
|
"""{"type":"object","properties":{"id":{"type":"integer"},"label":{"type":"string"}},"required":["id"]}""",
|
|
json);
|
|
}
|
|
|
|
/// <summary>Verifies that serializing an array includes its items.</summary>
|
|
[Fact]
|
|
public void Serialize_Array_IncludesItems()
|
|
{
|
|
var node = new SchemaNode { Type = "array", Items = new SchemaNode { Type = "string" } };
|
|
Assert.Equal("""{"type":"array","items":{"type":"string"}}""", SchemaBuilderModel.Serialize(node));
|
|
}
|
|
|
|
/// <summary>Verifies that properties with a blank name are skipped when serializing.</summary>
|
|
[Fact]
|
|
public void Serialize_PropertiesWithBlankName_Skipped()
|
|
{
|
|
var node = new SchemaNode { Type = "object" };
|
|
node.Properties.Add(new SchemaProperty { Name = "", Schema = new SchemaNode { Type = "integer" } });
|
|
node.Properties.Add(new SchemaProperty { Name = "valid", Schema = new SchemaNode { Type = "string" } });
|
|
|
|
var json = SchemaBuilderModel.Serialize(node);
|
|
Assert.Equal("""{"type":"object","properties":{"valid":{"type":"string"}},"required":["valid"]}""", json);
|
|
}
|
|
|
|
// ── Round-trip ────────────────────────────────────────────────────────────
|
|
|
|
/// <summary>Verifies that parsing and then serializing a schema round-trips to a stable result.</summary>
|
|
[Fact]
|
|
public void RoundTrip_Parse_Then_Serialize_Stable()
|
|
{
|
|
const string original = """{"type":"object","properties":{"id":{"type":"integer"},"tags":{"type":"array","items":{"type":"string"}}},"required":["id"]}""";
|
|
var node = SchemaBuilderModel.Parse(original, SchemaBuilderModel.NewObject());
|
|
var roundTripped = SchemaBuilderModel.Serialize(node);
|
|
Assert.Equal(original, roundTripped);
|
|
}
|
|
}
|