feat(uns): S7/AbCip/AbLegacy/TwinCAT/Focas typed tag-config editors (F-uns-1 T4-T8)
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors;
|
||||
using ZB.MOM.WW.OtOpcUa.Driver.AbCip;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Uns;
|
||||
|
||||
public sealed class AbCipTagConfigModelTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("")]
|
||||
[InlineData(" ")]
|
||||
[InlineData("{}")]
|
||||
public void FromJson_returns_defaults_for_empty_input(string? json)
|
||||
{
|
||||
var m = AbCipTagConfigModel.FromJson(json);
|
||||
|
||||
m.DeviceHostAddress.ShouldBe("");
|
||||
m.TagPath.ShouldBe("");
|
||||
m.DataType.ShouldBe(AbCipDataType.DInt);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Round_trip_preserves_all_fields()
|
||||
{
|
||||
var m = new AbCipTagConfigModel
|
||||
{
|
||||
DeviceHostAddress = "ab://gw/1,0",
|
||||
TagPath = "Program:Main.Speed",
|
||||
DataType = AbCipDataType.Real,
|
||||
};
|
||||
|
||||
var json = m.ToJson();
|
||||
var m2 = AbCipTagConfigModel.FromJson(json);
|
||||
|
||||
m2.DeviceHostAddress.ShouldBe("ab://gw/1,0");
|
||||
m2.TagPath.ShouldBe("Program:Main.Speed");
|
||||
m2.DataType.ShouldBe(AbCipDataType.Real);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ToJson_emits_camelCase_keys_with_enum_names()
|
||||
{
|
||||
var m = new AbCipTagConfigModel
|
||||
{
|
||||
DeviceHostAddress = "ab://gw/1,0",
|
||||
TagPath = "Motor1.Status",
|
||||
DataType = AbCipDataType.DInt,
|
||||
};
|
||||
|
||||
var json = m.ToJson();
|
||||
|
||||
json.ShouldContain("\"deviceHostAddress\":\"ab://gw/1,0\"");
|
||||
json.ShouldContain("\"tagPath\":\"Motor1.Status\"");
|
||||
json.ShouldContain("\"dataType\":\"DInt\"");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FromJson_then_ToJson_preserves_unknown_keys()
|
||||
{
|
||||
var json = AbCipTagConfigModel
|
||||
.FromJson("""{"tagPath":"Motor1.Status","extraKey":"keepme"}""")
|
||||
.ToJson();
|
||||
|
||||
json.ShouldContain("extraKey");
|
||||
json.ShouldContain("keepme");
|
||||
json.ShouldContain("\"tagPath\":\"Motor1.Status\"");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_returns_error_when_tagPath_blank()
|
||||
{
|
||||
new AbCipTagConfigModel { TagPath = "" }.Validate().ShouldNotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_returns_null_when_tagPath_filled()
|
||||
{
|
||||
new AbCipTagConfigModel { TagPath = "Motor1.Status" }.Validate().ShouldBeNull();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors;
|
||||
using ZB.MOM.WW.OtOpcUa.Driver.AbLegacy;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Uns;
|
||||
|
||||
public sealed class AbLegacyTagConfigModelTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("")]
|
||||
[InlineData(" ")]
|
||||
[InlineData("{}")]
|
||||
public void FromJson_returns_defaults_for_empty_input(string? json)
|
||||
{
|
||||
var m = AbLegacyTagConfigModel.FromJson(json);
|
||||
|
||||
m.DeviceHostAddress.ShouldBe("");
|
||||
m.Address.ShouldBe("");
|
||||
m.DataType.ShouldBe(AbLegacyDataType.Int);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Round_trip_preserves_all_fields()
|
||||
{
|
||||
var m = new AbLegacyTagConfigModel
|
||||
{
|
||||
DeviceHostAddress = "ab://10.0.0.5",
|
||||
Address = "N7:0",
|
||||
DataType = AbLegacyDataType.Float,
|
||||
};
|
||||
|
||||
var json = m.ToJson();
|
||||
var m2 = AbLegacyTagConfigModel.FromJson(json);
|
||||
|
||||
m2.DeviceHostAddress.ShouldBe("ab://10.0.0.5");
|
||||
m2.Address.ShouldBe("N7:0");
|
||||
m2.DataType.ShouldBe(AbLegacyDataType.Float);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ToJson_emits_camelCase_keys_with_enum_names()
|
||||
{
|
||||
var m = new AbLegacyTagConfigModel
|
||||
{
|
||||
DeviceHostAddress = "ab://10.0.0.5",
|
||||
Address = "N7:0",
|
||||
DataType = AbLegacyDataType.Int,
|
||||
};
|
||||
|
||||
var json = m.ToJson();
|
||||
|
||||
json.ShouldContain("\"deviceHostAddress\":\"ab://10.0.0.5\"");
|
||||
json.ShouldContain("\"address\":\"N7:0\"");
|
||||
json.ShouldContain("\"dataType\":\"Int\"");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FromJson_then_ToJson_preserves_unknown_keys()
|
||||
{
|
||||
var json = AbLegacyTagConfigModel
|
||||
.FromJson("""{"address":"N7:0","extraKey":"keepme"}""")
|
||||
.ToJson();
|
||||
|
||||
json.ShouldContain("extraKey");
|
||||
json.ShouldContain("keepme");
|
||||
json.ShouldContain("\"address\":\"N7:0\"");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_returns_error_when_address_blank()
|
||||
{
|
||||
new AbLegacyTagConfigModel { Address = "" }.Validate().ShouldNotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_returns_null_when_address_filled()
|
||||
{
|
||||
new AbLegacyTagConfigModel { Address = "N7:0" }.Validate().ShouldBeNull();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors;
|
||||
using ZB.MOM.WW.OtOpcUa.Driver.FOCAS;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Uns;
|
||||
|
||||
public sealed class FocasTagConfigModelTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("")]
|
||||
[InlineData(" ")]
|
||||
[InlineData("{}")]
|
||||
public void FromJson_returns_defaults_for_empty_input(string? json)
|
||||
{
|
||||
var m = FocasTagConfigModel.FromJson(json);
|
||||
|
||||
m.DeviceHostAddress.ShouldBe("");
|
||||
m.Address.ShouldBe("");
|
||||
m.DataType.ShouldBe(FocasDataType.Int32);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Round_trip_preserves_all_fields()
|
||||
{
|
||||
var m = new FocasTagConfigModel
|
||||
{
|
||||
DeviceHostAddress = "192.168.0.1:8193",
|
||||
Address = "MACRO:500",
|
||||
DataType = FocasDataType.Float64,
|
||||
};
|
||||
|
||||
var json = m.ToJson();
|
||||
var m2 = FocasTagConfigModel.FromJson(json);
|
||||
|
||||
m2.DeviceHostAddress.ShouldBe("192.168.0.1:8193");
|
||||
m2.Address.ShouldBe("MACRO:500");
|
||||
m2.DataType.ShouldBe(FocasDataType.Float64);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ToJson_emits_camelCase_keys_with_enum_names()
|
||||
{
|
||||
var m = new FocasTagConfigModel
|
||||
{
|
||||
DeviceHostAddress = "192.168.0.1:8193",
|
||||
Address = "R100",
|
||||
DataType = FocasDataType.Int32,
|
||||
};
|
||||
|
||||
var json = m.ToJson();
|
||||
|
||||
json.ShouldContain("\"deviceHostAddress\":\"192.168.0.1:8193\"");
|
||||
json.ShouldContain("\"address\":\"R100\"");
|
||||
json.ShouldContain("\"dataType\":\"Int32\"");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FromJson_then_ToJson_preserves_unknown_keys()
|
||||
{
|
||||
var json = FocasTagConfigModel
|
||||
.FromJson("""{"address":"R100","extraKey":"keepme"}""")
|
||||
.ToJson();
|
||||
|
||||
json.ShouldContain("extraKey");
|
||||
json.ShouldContain("keepme");
|
||||
json.ShouldContain("\"address\":\"R100\"");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_returns_error_when_address_blank()
|
||||
{
|
||||
new FocasTagConfigModel { Address = "" }.Validate().ShouldNotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_returns_null_when_address_filled()
|
||||
{
|
||||
new FocasTagConfigModel { Address = "R100" }.Validate().ShouldBeNull();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors;
|
||||
using ZB.MOM.WW.OtOpcUa.Driver.S7;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Uns;
|
||||
|
||||
public sealed class S7TagConfigModelTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("")]
|
||||
[InlineData(" ")]
|
||||
[InlineData("{}")]
|
||||
public void FromJson_returns_defaults_for_empty_input(string? json)
|
||||
{
|
||||
var m = S7TagConfigModel.FromJson(json);
|
||||
|
||||
m.Address.ShouldBe("");
|
||||
m.DataType.ShouldBe(S7DataType.Int16);
|
||||
m.StringLength.ShouldBe(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Round_trip_preserves_all_fields()
|
||||
{
|
||||
var m = new S7TagConfigModel
|
||||
{
|
||||
Address = "DB1.DBW0",
|
||||
DataType = S7DataType.Float32,
|
||||
StringLength = 32,
|
||||
};
|
||||
|
||||
var json = m.ToJson();
|
||||
var m2 = S7TagConfigModel.FromJson(json);
|
||||
|
||||
m2.Address.ShouldBe("DB1.DBW0");
|
||||
m2.DataType.ShouldBe(S7DataType.Float32);
|
||||
m2.StringLength.ShouldBe(32);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ToJson_emits_camelCase_keys_with_enum_names()
|
||||
{
|
||||
var m = new S7TagConfigModel
|
||||
{
|
||||
Address = "M0.0",
|
||||
DataType = S7DataType.Bool,
|
||||
StringLength = 0,
|
||||
};
|
||||
|
||||
var json = m.ToJson();
|
||||
|
||||
json.ShouldContain("\"address\":\"M0.0\"");
|
||||
json.ShouldContain("\"dataType\":\"Bool\"");
|
||||
json.ShouldContain("\"stringLength\":0");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FromJson_then_ToJson_preserves_unknown_keys()
|
||||
{
|
||||
var json = S7TagConfigModel
|
||||
.FromJson("""{"address":"DB1.DBW0","extraKey":"keepme"}""")
|
||||
.ToJson();
|
||||
|
||||
json.ShouldContain("extraKey");
|
||||
json.ShouldContain("keepme");
|
||||
json.ShouldContain("\"address\":\"DB1.DBW0\"");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_returns_error_when_address_blank()
|
||||
{
|
||||
new S7TagConfigModel { Address = "" }.Validate().ShouldNotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_returns_null_when_address_filled()
|
||||
{
|
||||
new S7TagConfigModel { Address = "DB1.DBW0" }.Validate().ShouldBeNull();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors;
|
||||
using ZB.MOM.WW.OtOpcUa.Driver.TwinCAT;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Uns;
|
||||
|
||||
public sealed class TwinCATTagConfigModelTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("")]
|
||||
[InlineData(" ")]
|
||||
[InlineData("{}")]
|
||||
public void FromJson_returns_defaults_for_empty_input(string? json)
|
||||
{
|
||||
var m = TwinCATTagConfigModel.FromJson(json);
|
||||
|
||||
m.DeviceHostAddress.ShouldBe("");
|
||||
m.SymbolPath.ShouldBe("");
|
||||
m.DataType.ShouldBe(TwinCATDataType.DInt);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Round_trip_preserves_all_fields()
|
||||
{
|
||||
var m = new TwinCATTagConfigModel
|
||||
{
|
||||
DeviceHostAddress = "5.1.2.3.1.1:851",
|
||||
SymbolPath = "MAIN.bStart",
|
||||
DataType = TwinCATDataType.Real,
|
||||
};
|
||||
|
||||
var json = m.ToJson();
|
||||
var m2 = TwinCATTagConfigModel.FromJson(json);
|
||||
|
||||
m2.DeviceHostAddress.ShouldBe("5.1.2.3.1.1:851");
|
||||
m2.SymbolPath.ShouldBe("MAIN.bStart");
|
||||
m2.DataType.ShouldBe(TwinCATDataType.Real);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ToJson_emits_camelCase_keys_with_enum_names()
|
||||
{
|
||||
var m = new TwinCATTagConfigModel
|
||||
{
|
||||
DeviceHostAddress = "5.1.2.3.1.1:851",
|
||||
SymbolPath = "GVL.Counter",
|
||||
DataType = TwinCATDataType.DInt,
|
||||
};
|
||||
|
||||
var json = m.ToJson();
|
||||
|
||||
json.ShouldContain("\"deviceHostAddress\":\"5.1.2.3.1.1:851\"");
|
||||
json.ShouldContain("\"symbolPath\":\"GVL.Counter\"");
|
||||
json.ShouldContain("\"dataType\":\"DInt\"");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FromJson_then_ToJson_preserves_unknown_keys()
|
||||
{
|
||||
var json = TwinCATTagConfigModel
|
||||
.FromJson("""{"symbolPath":"GVL.Counter","extraKey":"keepme"}""")
|
||||
.ToJson();
|
||||
|
||||
json.ShouldContain("extraKey");
|
||||
json.ShouldContain("keepme");
|
||||
json.ShouldContain("\"symbolPath\":\"GVL.Counter\"");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_returns_error_when_symbolPath_blank()
|
||||
{
|
||||
new TwinCATTagConfigModel { SymbolPath = "" }.Validate().ShouldNotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Validate_returns_null_when_symbolPath_filled()
|
||||
{
|
||||
new TwinCATTagConfigModel { SymbolPath = "MAIN.bStart" }.Validate().ShouldBeNull();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user