using BuildFlow.Shared.Domain.Errors; using BuildFlow.Shared.Domain.Exceptions; using FluentAssertions; using System.Text.Json.Nodes; using Workflow.Application.Form.Derivation; using Workflow.Application.Form.Schema; using Xunit; namespace BuildFlow.Workflow.Tests.Performance; /// /// 预解析表单 Schema 在批量校验和派生中的复用测试。 /// public class PreparedFormSchemaTests { [Fact] public async Task PreparedSchemaCanBeReusedForValidationAndDerivation() { var prepared = PreparedFormSchema.Create(ComputedSchema); var derivation = new FormValueDerivationService([], []); var firstValidation = FormDataValidator.Validate( prepared, """{"quantity":2,"unitPrice":10}"""); var first = await derivation.DeriveAsync( prepared, """{"quantity":2,"unitPrice":10}""", new FormDerivationContext(Guid.NewGuid(), Guid.NewGuid(), null), CancellationToken.None); var second = await derivation.DeriveAsync( prepared, """{"quantity":3,"unitPrice":5}""", new FormDerivationContext(Guid.NewGuid(), Guid.NewGuid(), null), CancellationToken.None); firstValidation.IsValid.Should().BeTrue(); ReadTotal(first.DataJson).Should().Be(20); ReadTotal(second.DataJson).Should().Be(15); prepared.Validation.Fields.Should().HaveCount(3); } [Fact] public void InvalidSchemaCannotBePrepared() { var act = () => PreparedFormSchema.Create(""" { "type": "object", "properties": { "supplier": { "type": "object", "x-component": "RelationPicker", "x-field-kind": "relation", "x-relation": { "idField": "id" } } } } """); var exception = act.Should().Throw().Which; exception.Code.Should().Be(ErrorCode.InvalidParam); } private static decimal ReadTotal(string dataJson) => JsonNode.Parse(dataJson)!["total"]!.GetValue(); private const string ComputedSchema = """ { "type": "object", "properties": { "quantity": { "type": "number", "x-component": "InputNumber" }, "unitPrice": { "type": "number", "x-component": "InputNumber" }, "total": { "type": "number", "x-component": "InputNumber", "x-field-kind": "computed", "x-derived": { "mode": "computed", "writePolicy": "overwrite", "expression": { "operator": "multiply", "left": { "type": "field", "path": "quantity" }, "right": { "type": "field", "path": "unitPrice" } } } } } } """; }