using ZB.MOM.WW.OtOpcUa.Driver.AbCip; namespace ZB.MOM.WW.OtOpcUa.Driver.AbCip.Tests; /// /// Test fake for . Stores the mock PLC value in /// + returns it from . Use /// to simulate libplctag error codes, /// / to simulate exceptions. /// internal class FakeAbCipTag : IAbCipTagRuntime { public AbCipTagCreateParams CreationParams { get; } public object? Value { get; set; } public int Status { get; set; } public bool ThrowOnInitialize { get; set; } public bool ThrowOnRead { get; set; } public Exception? Exception { get; set; } public int InitializeCount { get; private set; } public int ReadCount { get; private set; } public int WriteCount { get; private set; } public bool Disposed { get; private set; } public FakeAbCipTag(AbCipTagCreateParams createParams) => CreationParams = createParams; public virtual Task InitializeAsync(CancellationToken cancellationToken) { InitializeCount++; if (ThrowOnInitialize) throw Exception ?? new InvalidOperationException("fake initialize failure"); return Task.CompletedTask; } public virtual Task ReadAsync(CancellationToken cancellationToken) { ReadCount++; if (ThrowOnRead) throw Exception ?? new InvalidOperationException("fake read failure"); return Task.CompletedTask; } public virtual Task WriteAsync(CancellationToken cancellationToken) { WriteCount++; return Task.CompletedTask; } public virtual int GetStatus() => Status; public virtual object? DecodeValue(AbCipDataType type, int? bitIndex) => Value; public virtual void EncodeValue(AbCipDataType type, int? bitIndex, object? value) => Value = value; public virtual void Dispose() => Disposed = true; } /// Test factory that produces s and indexes them for assertion. internal sealed class FakeAbCipTagFactory : IAbCipTagFactory { public Dictionary Tags { get; } = new(StringComparer.OrdinalIgnoreCase); public Func? Customise { get; set; } public IAbCipTagRuntime Create(AbCipTagCreateParams createParams) { var fake = Customise?.Invoke(createParams) ?? new FakeAbCipTag(createParams); Tags[createParams.TagName] = fake; return fake; } }