@Test
  public void shouldDecodeCorrectly() {
    final ByteBuffer encodedMsgBuffer = ByteBuffer.allocateDirect(MSG_BUFFER_CAPACITY);
    encodeTestMessage(encodedMsgBuffer);

    final DirectBuffer decodeBuffer = new UnsafeBuffer(encodedMsgBuffer);

    final MessageHeaderDecoder hdrDecoder = new MessageHeaderDecoder();
    final MsgDecoder msgDecoder = new MsgDecoder();

    hdrDecoder.wrap(decodeBuffer, 0);
    msgDecoder.wrap(
        decodeBuffer,
        hdrDecoder.encodedLength(),
        MSG_ENCODER.sbeBlockLength(),
        MSG_ENCODER.sbeSchemaVersion());

    assertThat(hdrDecoder.blockLength(), is(22));
    assertThat(hdrDecoder.templateId(), is(1));
    assertThat(hdrDecoder.schemaId(), is(3));
    assertThat(hdrDecoder.version(), is(0));

    assertThat(msgDecoder.structure().enumOne(), is(EnumOne.Value10));
    assertThat(msgDecoder.structure().zeroth(), is((short) 42));
    assertThat(msgDecoder.structure().setOne().bit0(), is(false));
    assertThat(msgDecoder.structure().setOne().bit16(), is(true));
    assertThat(msgDecoder.structure().setOne().bit26(), is(false));
    assertThat(msgDecoder.structure().inner().first(), is(101L));
    assertThat(msgDecoder.structure().inner().second(), is(202L));

    assertThat(msgDecoder.encodedLength(), is(22));
  }
  private static int encodeTestMessage(final ByteBuffer buffer) {
    final UnsafeBuffer directBuffer = new UnsafeBuffer(buffer);

    int bufferOffset = 0;
    MESSAGE_HEADER
        .wrap(directBuffer, bufferOffset)
        .blockLength(MSG_ENCODER.sbeBlockLength())
        .templateId(MSG_ENCODER.sbeTemplateId())
        .schemaId(MSG_ENCODER.sbeSchemaId())
        .version(MSG_ENCODER.sbeSchemaVersion());

    bufferOffset += MESSAGE_HEADER.encodedLength();

    MSG_ENCODER
        .wrap(directBuffer, bufferOffset)
        .structure()
        .enumOne(EnumOne.Value10)
        .zeroth((byte) 42);

    MSG_ENCODER.structure().setOne().clear().bit0(false).bit16(true).bit26(false);

    MSG_ENCODER.structure().inner().first(101).second(202);

    return MSG_ENCODER.encodedLength();
  }
  @Test
  public void shouldOtfDecodeCorrectly() throws Exception {
    final ByteBuffer encodedSchemaBuffer = ByteBuffer.allocateDirect(SCHEMA_BUFFER_CAPACITY);
    encodeSchema(encodedSchemaBuffer);

    final ByteBuffer encodedMsgBuffer = ByteBuffer.allocateDirect(MSG_BUFFER_CAPACITY);
    encodeTestMessage(encodedMsgBuffer);

    encodedSchemaBuffer.flip();
    final Ir ir = decodeIr(encodedSchemaBuffer);

    final DirectBuffer decodeBuffer = new UnsafeBuffer(encodedMsgBuffer);
    final OtfHeaderDecoder otfHeaderDecoder = new OtfHeaderDecoder(ir.headerStructure());

    assertThat(otfHeaderDecoder.getBlockLength(decodeBuffer, 0), is(22));
    assertThat(otfHeaderDecoder.getSchemaId(decodeBuffer, 0), is(3));
    assertThat(otfHeaderDecoder.getTemplateId(decodeBuffer, 0), is(1));
    assertThat(otfHeaderDecoder.getSchemaVersion(decodeBuffer, 0), is(0));

    final TokenListener mockTokenListener = mock(TokenListener.class);

    OtfMessageDecoder.decode(
        decodeBuffer,
        otfHeaderDecoder.encodedLength(),
        MSG_ENCODER.sbeSchemaVersion(),
        MSG_ENCODER.sbeBlockLength(),
        ir.getMessage(MSG_ENCODER.sbeTemplateId()),
        mockTokenListener);

    final InOrder inOrder = inOrder(mockTokenListener);
    inOrder.verify(mockTokenListener).onBeginComposite(any(), any(), eq(2), eq(17));
    inOrder
        .verify(mockTokenListener)
        .onEnum(any(), eq(decodeBuffer), eq(8), any(), eq(3), eq(6), eq(0));
    inOrder.verify(mockTokenListener).onEncoding(any(), eq(decodeBuffer), eq(9), any(), eq(0));
    inOrder
        .verify(mockTokenListener)
        .onBitSet(any(), eq(decodeBuffer), eq(10), any(), eq(8), eq(12), eq(0));
    inOrder.verify(mockTokenListener).onBeginComposite(any(), any(), eq(13), eq(16));
    inOrder.verify(mockTokenListener).onEncoding(any(), eq(decodeBuffer), eq(14), any(), eq(0));
    inOrder.verify(mockTokenListener).onEncoding(any(), eq(decodeBuffer), eq(22), any(), eq(0));
    inOrder.verify(mockTokenListener).onEndComposite(any(), any(), eq(13), eq(16));
    inOrder.verify(mockTokenListener).onEndComposite(any(), any(), eq(2), eq(17));
  }