@Test
  public void shouldTrackAbsolutePosition() throws Exception {
    // GIVEN
    String[][] data =
        new String[][] {
          {"this is", "the first line"}, // 21+delimiter+newline = 23 characters
          {"where this", "is the second line"}, // 28+delimiter+newline = 30 characters
        };
    RawIterator<Reader, IOException> readers = readerIteratorFromStrings(data, '\n');
    CharReadable reader = Readables.sources(readers);
    assertEquals(0L, reader.position());
    SectionedCharBuffer buffer = new SectionedCharBuffer(15);

    // WHEN
    reader.read(buffer, buffer.front());
    assertEquals(15, reader.position());
    reader.read(buffer, buffer.front());
    assertEquals(
        "Should not transition to a new reader in the middle of a read", 23, reader.position());
    assertEquals("Reader1", reader.sourceDescription());

    // we will transition to the new reader in the call below
    reader.read(buffer, buffer.front());
    assertEquals(23 + 15, reader.position());
    reader.read(buffer, buffer.front());
    assertEquals(23 + 30, reader.position());
    reader.read(buffer, buffer.front());
    assertFalse(buffer.hasAvailable());
  }
  @Test
  public void shouldHandleSourcesEndingWithNewLine() throws Exception {
    // GIVEN
    String[][] data =
        new String[][] {
          {"this is", "the first line"},
          {"where this", "is the second line"},
        };

    // WHEN
    RawIterator<Reader, IOException> readers = readerIteratorFromStrings(data, '\n');
    CharSeeker seeker = CharSeekers.charSeeker(Readables.sources(readers), 200, true, '"');

    // WHEN/THEN
    for (String[] line : data) {
      assertNextLine(line, seeker, mark, extractors);
    }
    assertFalse(seeker.seek(mark, delimiter));
    seeker.close();
  }