using Microsoft.Data.SqlClient.Server; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Core.Abstractions; namespace ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer.Tests; public sealed class SampleRowMapperTests { public static TheoryData Values => new() { HistorianValue.FromDouble(12.5), HistorianValue.FromInt64(long.MinValue + 3), HistorianValue.FromBoolean(true), HistorianValue.FromBoolean(false), HistorianValue.FromString("héllo"), HistorianValue.FromString(""), HistorianValue.FromDateTime(new DateTime(2026, 10, 9, 1, 2, 3, DateTimeKind.Utc).AddTicks(1234567)), HistorianValue.Empty, }; [Theory] [MemberData(nameof(Values))] public void Every_kind_round_trips_through_the_column_quad(HistorianValue v) { var c = SampleRowMapper.ToColumns(v); SampleRowMapper.FromColumns(c.ValueKind, c.NumValue, c.IntValue, c.StrValue).ShouldBe(v); } [Fact] public void Columns_follow_the_spec_mapping() { SampleRowMapper.ToColumns(HistorianValue.FromInt64(7)).ShouldBe(new SampleColumns(2, 7d, 7L, null)); SampleRowMapper.ToColumns(HistorianValue.FromBoolean(true)).ShouldBe(new SampleColumns(3, 1d, 1L, null)); SampleRowMapper.ToColumns(HistorianValue.FromDouble(1.5)).ShouldBe(new SampleColumns(1, 1.5, null, null)); SampleRowMapper.ToColumns(HistorianValue.Empty).ShouldBe(new SampleColumns(0, null, null, null)); } [Fact] public void Status_is_stored_bit_for_bit() { SampleRowMapper.ToDbStatus(0x80050000u).ShouldBeLessThan(0); SampleRowMapper.FromDbStatus(SampleRowMapper.ToDbStatus(0x80050000u)).ShouldBe(0x80050000u); } [Fact] public void Sample_records_keep_sub_millisecond_ticks() { var t = new DateTime(2026, 10, 9, 0, 0, 0, DateTimeKind.Utc).AddTicks(1234567); var rec = SampleRowMapper.ToSampleRecords([new SqlSampleRow(t, HistorianValue.FromDouble(2), 0x80050000u)]).Single(); rec.GetDateTime(0).Ticks.ShouldBe(t.Ticks); rec.GetByte(1).ShouldBe((byte)1); rec.GetDouble(2).ShouldBe(2d); rec.IsDBNull(3).ShouldBeTrue(); rec.IsDBNull(4).ShouldBeTrue(); rec.GetInt32(5).ShouldBe(unchecked((int)0x80050000u)); } [Fact] public void Time_records_keep_sub_millisecond_ticks() { var t = new DateTime(2026, 10, 9, 0, 0, 0, DateTimeKind.Utc).AddTicks(1234567); SampleRowMapper.ToTimeRecords([t]).Single().GetDateTime(0).Ticks.ShouldBe(t.Ticks); } }