Skip to content

Commit

Permalink
CheckFieldsHaveValues to work for non-strings
Browse files Browse the repository at this point in the history
  • Loading branch information
gbirchmeier committed Jun 12, 2020
1 parent 0561770 commit b07a666
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 5 deletions.
13 changes: 11 additions & 2 deletions QuickFIXn/DataDictionary/DataDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,19 @@ public void CheckValidFormat(Fields.IField field)
Type type;
if (!TryGetFieldType(field.Tag, out type))
return;

if (type == typeof(StringField))
return;
else if (type == typeof(CharField))

if (false == CheckFieldsHaveValues && field.ToString().Length < 1)
{
// If ValidateFieldsHaveValues=N, don't check empty non-string fields
// because engine should not decide how to convert empty to e.g. float or datetime.
// (User code may see IncorrectDataFormat exceptions
// when attempting to extract fields in not-string formats.)
return;
}

if (type == typeof(CharField))
Fields.Converters.CharConverter.Convert(field.ToString());
else if (type == typeof(IntField))
Fields.Converters.IntConverter.Convert(field.ToString());
Expand Down
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ What's New
* (patch) #592/#601 - better detection of malformed DD elements (gbirchmeier/roederja2)
* (patch) #606 - fix IDisposable implementations to follow MS general pattern (pavka1799)
* (patch) #566 - SSLValidateCertificates=N overrides SSLCheckCertificateRevocation (gbirchmeier, h/t to Mad-Lynx)
* (patch) #405 - CheckFieldsHaveValues needs to work for non-strings too (gbirchmeier)

### v1.9.0:
* (minor) #469 - Add support for NET Standard 2.0 (jhickson)
Expand Down
71 changes: 68 additions & 3 deletions UnitTests/DataDictionaryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,71 @@ public void TrailerTest()
Assert.That(dd.Trailer.Fields.Count, Is.EqualTo(3));
}

[Test]
public void CheckValidFormat()
{
QuickFix.DataDictionary.DataDictionary dd = new QuickFix.DataDictionary.DataDictionary();
dd.LoadFIXSpec("FIX44");
dd.CheckFieldsHaveValues = true;

var goodFields = new QuickFix.Fields.StringField[] {
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.Symbol, "foo"), // string
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.Side, "2"), // char
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.LastQty, "123"), // int
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.AvgPx, "1.23"), // decimal
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.ReportToExch, "Y"), // bool
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.ContraTradeTime, "20011217-09:30:47.123"), // datetime
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.MDEntryDate, "20030910"), // dateonly
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.MDEntryTime, "13:20:00.123"), // timeonly

new QuickFix.Fields.StringField(QuickFix.Fields.Tags.Symbol, "") // string
};

foreach (var datum in goodFields)
{
Assert.DoesNotThrow(delegate { dd.CheckValidFormat(datum); });
}

var badFields = new QuickFix.Fields.StringField[]
{
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.Side, "toolong"), // char
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.LastQty, "notint"), // int
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.AvgPx, "notdec"), // decimal
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.ReportToExch, "notbool"), // bool
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.ContraTradeTime, "notdatetime"), // datetime
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.MDEntryDate, "notdate"), // dateonly
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.MDEntryTime, "nottime") // timeonly
};

foreach (var datum in badFields)
{
Assert.Throws(typeof(IncorrectDataFormat), delegate { dd.CheckValidFormat(datum); });
}

var emptyFields = new QuickFix.Fields.StringField[]
{
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.Side, ""), // char
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.LastQty, ""), // int
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.AvgPx, ""), // decimal
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.ReportToExch, ""), // bool
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.ContraTradeTime, ""), // datetime
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.MDEntryDate, ""), // dateonly
new QuickFix.Fields.StringField(QuickFix.Fields.Tags.MDEntryTime, "") // timeonly
};

foreach (var datum in emptyFields)
{
Assert.Throws(typeof(IncorrectDataFormat), delegate { dd.CheckValidFormat(datum); });
}

// Setting change!
dd.CheckFieldsHaveValues = false;
foreach (var datum in emptyFields)
{
Assert.DoesNotThrow(delegate { dd.CheckValidFormat(datum); });
}
}

[Test]
public void CheckValidTagNumberTest()
{
Expand Down Expand Up @@ -578,10 +643,10 @@ public void ValidateTagSpecifiedWithoutAValue()
{
QuickFix.DataDictionary.DataDictionary dd = new QuickFix.DataDictionary.DataDictionary();
dd.LoadFIXSpec("FIX42");
QuickFix.FIX44.MessageFactory f = new QuickFix.FIX44.MessageFactory();
QuickFix.FIX42.MessageFactory f = new QuickFix.FIX42.MessageFactory();

string[] msgFields = {"8=FIX.4.2", "9=65", "35=B", "34=3", "49=sender", "52=20110909-09:09:09.999", "56=target",
"148=", "33=0", "10=188"};
string[] msgFields = {"8=FIX.4.2", "9=70", "35=B", "34=3", "49=sender", "52=20110909-09:09:09.999", "56=target",
"358=", "148=", "33=0", "10=150"};
string msgStr = String.Join(Message.SOH, msgFields) + Message.SOH;

string msgType = "B";
Expand Down

0 comments on commit b07a666

Please sign in to comment.