/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.f1x.v1;
import org.junit.Assert;
import org.junit.Test;
import org.f1x.api.message.MessageBuilder;
import org.f1x.api.message.Tools;
import org.f1x.api.message.fields.MsgType;
import org.f1x.api.message.fields.OrdRejReason;
import org.f1x.api.message.fields.Side;
import org.f1x.api.message.types.ByteEnumLookup;
import org.f1x.api.message.types.IntEnumLookup;
import org.f1x.util.ByteArrayReference;
import org.f1x.util.TestUtils;
import org.f1x.util.format.TimestampFormatter;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.TimeZone;
import static org.junit.Assert.*;
public class Test_DefaultMessageParser {
private final DateFormat utcTimestampFormat = TestUtils.UTC_TIMESTAMP_FORMAT;
private DefaultMessageParser parser = new DefaultMessageParser();
@Test
public void testLogon() {
assertParser("8=FIX.4.4\u00019=116\u000135=A\u000134=1\u000149=DEMO2Kweoj_DEMOFIX\u000152=20121009-13:14:57.089\u000156=DUKASCOPYFIX\u000198=0\u0001108=30\u0001141=Y\u0001553=DEMO2Kweoj\u0001554=**********\u000110=202\u0001");
}
@Test
public void testNewOrderSingle() {
assertParser("8=FIX.4.4\u00019=144\u000135=D\u000134=6\u000149=DEMO2Kweoj_DEMOFIX\u000152=20121009-13:59:01.666\u000156=DUKASCOPYFIX\u000111=512\u000121=1\u000138=1000\u000140=1\u000154=1\u000155=EUR/USD\u000159=1\u000160=20121009-13:59:01.666\u000110=000\u0001");
}
@Test
public void testExecutionReport() {
assertParser("8=FIX.4.4\u00019=251\u000135=8\u000134=7\u000149=DUKASCOPYFIX\u000152=20121009-13:59:21.158\u000156=DEMO2Kweoj_DEMOFIX\u00016=0\u000111=506\u000114=0\u000117=506\u000137=506\u000138=0\u000139=8\u000154=7\u000155=UNKNOWN\u000158=Your order has been rejected due to validation failure. Order amount can't be less than <MIN_OPEN_AMOUNT>\u0001150=8\u0001151=0\u000110=196\u0001");
}
@Test
public void testBasicTypesParser() throws ParseException {
String order = "8=FIX.4.4\u00019=144\u000135=D\u000134=6\u000149=DEMO2Kweoj_DEMOFIX\u000152=20121009-13:59:01.666\u000156=DUKASCOPYFIX\u000111=512\u000121=1\u000138=1000\u000140=1\u000154=1\u000155=EUR/USD\u000159=1\u000160=20121009-13:59:01.666\u000110=000\u0001";
String report = "8=FIX.4.4\u00019=251\u000135=8\u000134=7\u000149=DUKASCOPYFIX\u000152=20121009-13:59:21.158\u000156=DEMO2Kweoj_DEMOFIX\u00016=0\u000111=506\u000114=0\u000117=506\u000137=506\u000138=0\u000139=8\u000154=7\u000155=UNKNOWN\u000158=Your order has been rejected due to validation failure. Order amount can't be less than <MIN_OPEN_AMOUNT>\u0001150=8\u0001151=0\u000110=196\u0001";
parseTag (report, 49);
assertEquals("DUKASCOPYFIX", parser.getStringValue());
parseTag (report, 49);
assertTrue(Tools.equals("DUKASCOPYFIX", parser.getCharSequenceValue()));
parseTag (report, 11);
assertEquals(506, parser.getIntValue());
parseTag (report, 11);
assertEquals(506, parser.getLongValue());
parseTag (order, 59);
assertEquals('1', parser.getByteValue());
parseTag (order, 60);
assertEquals(utcTimestampFormat.parse("20121009-13:59:01.666").getTime(), parser.getUTCTimestampValue());
}
@Test
public void testEveryTypeParser () throws ParseException {
DateFormat localDateFormat = TestUtils.createDateFormat(TimestampFormatter.DATE_ONLY_FORMAT, TimeZone.getDefault());
MessageBuilder mb = new ByteBufferMessageBuilder(256, 5);
mb.add(1, "ABC");
mb.add(2, 123L);
mb.add(3, 123);
mb.add(4, 3.14159);
mb.add(5, (byte) 'x');
mb.add(6, true);
mb.add(7, false);
mb.add(8, Side.BUY);
mb.add(9, OrdRejReason.ORDER_EXCEEDS_LIMIT);
mb.add(10, MsgType.NEWS);
mb.addUTCTimestamp(11, TestUtils.parseUTCTimestamp("20121009-13:44:49.421"));
mb.addUTCDateOnly(12, TestUtils.parseUTCTimestamp("20121009-00:00:00.000"));
mb.addUTCTimeOnly(13, TestUtils.parseUTCTimestamp("20121009-13:44:49.421"));
mb.addLocalMktDate(14, localDateFormat.parse("20121122").getTime());
byte [] rawField = "RAW".getBytes();
mb.addRaw(15, rawField, 0, rawField.length);
byte [] buffer = new byte[mb.getLength()];
mb.output(buffer, 0);
assertMessageEquals("1=ABC|2=123|3=123|4=3.14159|5=x|6=Y|7=N|8=1|9=3|10=B|11=20121009-13:44:49.421|12=20121009|13=13:44:49.421|14=20121122|15=RAW|", new String(buffer));
DefaultMessageParser parser = new DefaultMessageParser();
parser.set(buffer, 0, buffer.length);
ByteEnumLookup<Side> sideByteEnumLookup = new ByteEnumLookup<>(Side.class);
IntEnumLookup<OrdRejReason> rejReasonIntEnumLookup = new IntEnumLookup<>(OrdRejReason.class);
//StringEnumLookup<Side> sideByteEnumLookup1 = new StringEnumLookup<>(Side.class);
ByteArrayReference array = new ByteArrayReference();
while (parser.next()) {
switch (parser.getTagNum()) {
case 1: assertEquals("ABC", String.valueOf(parser.getCharSequenceValue())); break;
case 2: assertEquals(123L, parser.getLongValue()); break;
case 3: assertEquals(123, parser.getIntValue()); break;
case 4: assertEquals(3.14159, parser.getDoubleValue(), 0.00001); break; // formatter is set to print 5 decimal places
case 5: assertEquals('x', parser.getByteValue()); break;
case 6: assertTrue(parser.getBooleanValue()); break;
case 7: assertFalse(parser.getBooleanValue()); break;
case 8: assertEquals(Side.BUY, sideByteEnumLookup.get(parser.getByteValue())); break;
case 9: assertEquals(OrdRejReason.ORDER_EXCEEDS_LIMIT, rejReasonIntEnumLookup.get(parser.getIntValue())); break;
//TODO:case 10: assertEquals(MsgType.NEWS, rejReasonIntEnumLookup.get(parser.getByteValue())); break;
case 11: assertEquals(TestUtils.parseUTCTimestamp("20121009-13:44:49.421"), parser.getUTCTimestampValue()); break;
case 12: assertEquals(TestUtils.parseUTCTimestamp("20121009-00:00:00.000"), parser.getUTCDateOnly()); break;
case 13: assertEquals(13*60*60000+ 44*60000 + 49*1000 +421, parser.getUTCTimeOnly()); break;
case 14:
assertEquals("20121122", localDateFormat.format(new Date(parser.getLocalMktDate())));
assertEquals(20121122, parser.getLocalMktDate2()); break;
case 15: parser.getByteSequence(array); assertEquals("RAW", array.toString()); break;
}
}
}
@Test
public void testReset () throws ParseException {
MessageBuilder mb = new ByteBufferMessageBuilder(256, 5);
mb.add(1, "ABC");
mb.add(2, 123L);
byte [] buffer = new byte[mb.getLength()];
mb.output(buffer, 0);
String expectedMessage = "1=ABC|2=123|";
assertMessageEquals(expectedMessage, new String(buffer));
DefaultMessageParser parser = new DefaultMessageParser();
parser.set(buffer, 0, buffer.length);
String parsedMessage = MessageParser2String.convert(parser);
assertMessageEquals(expectedMessage, parsedMessage);
parser.reset();
parsedMessage = MessageParser2String.convert(parser);
assertMessageEquals(expectedMessage, parsedMessage);
}
private void parseTag (String message, int tagNo) {
byte [] messageBytes = message.getBytes();
parser.set(messageBytes, 0, messageBytes.length);
while(parser.next()) {
if (parser.getTagNum() == tagNo)
return;
}
Assert.fail("Tag " + tagNo + " is not found");
}
private static void assertMessageEquals(String expected, String actual) {
Assert.assertEquals("Message equals", expected, actual.replace('\u0001', '|'));
}
private void assertParser(String message) {
byte [] messageBytes = message.getBytes();
parser.set(messageBytes, 0, messageBytes.length);
StringBuilder sb = new StringBuilder(messageBytes.length);
while (parser.next()) {
sb.append (parser.getTagNum());
sb.append ('=');
sb.append (parser.getCharSequenceValue());
sb.append ((char)1);
}
Assert.assertEquals(message, sb.toString());
}
}