import io
import pytest
from mrrc import MARCReader
class TestQueueStateMachine:
def test_first_call_reads_batch(self, fixture_1k):
reader = MARCReader(io.BytesIO(fixture_1k))
rec1 = next(reader)
assert rec1 is not None
assert rec1.leader() is not None
def test_subsequent_calls_use_queue(self, fixture_1k):
reader = MARCReader(io.BytesIO(fixture_1k))
rec1 = next(reader)
assert rec1 is not None
for i in range(99):
rec = next(reader)
assert rec is not None
if i > 0:
assert rec.leader() is not None
def test_eof_idempotence(self, fixture_1k):
reader = MARCReader(io.BytesIO(fixture_1k))
records = list(reader)
assert len(records) > 0
for _ in range(5):
with pytest.raises(StopIteration):
next(reader)
def test_iteration_semantic_unchanged(self, fixture_1k):
reader = MARCReader(io.BytesIO(fixture_1k))
records = list(reader)
assert len(records) == 1000
for rec in records:
assert rec.leader() is not None
def test_queue_reduces_gil_pressure(self, fixture_10k):
reader = MARCReader(io.BytesIO(fixture_10k))
records = []
for i, rec in enumerate(reader):
records.append(rec)
if i >= 99: break
assert len(records) == 100
for i, rec in enumerate(reader):
records.append(rec)
if i >= 99: break
assert len(records) == 200
def test_first_batch_boundary(self, fixture_1k):
reader = MARCReader(io.BytesIO(fixture_1k))
records = []
for i, rec in enumerate(reader):
records.append(rec)
if i >= 99: break
assert len(records) == 100
next_rec = next(reader)
assert next_rec is not None
def test_queue_ordering_preserved(self, fixture_1k):
reader = MARCReader(io.BytesIO(fixture_1k))
records = []
for i, rec in enumerate(reader):
records.append(rec)
if i >= 99:
break
assert len(records) == 100
for rec in records:
leader = rec.leader()
assert leader is not None
assert len(str(leader)) > 0
def test_read_record_legacy_api_uses_queue(self, fixture_1k):
reader = MARCReader(io.BytesIO(fixture_1k))
rec1 = reader.read_record()
assert rec1 is not None
rec2 = reader.read_record()
assert rec2 is not None
def test_mixed_iteration_and_read_record(self, fixture_1k):
reader = MARCReader(io.BytesIO(fixture_1k))
rec1 = next(reader)
assert rec1 is not None
rec2 = reader.read_record()
assert rec2 is not None
rec3 = next(reader)
assert rec3 is not None
def test_reader_repr_reflects_state(self, fixture_1k):
reader = MARCReader(io.BytesIO(fixture_1k))
repr_str = repr(reader)
assert repr_str is not None
assert "MARCReader" in repr_str
list(reader)
repr_str2 = repr(reader)
assert repr_str2 is not None
class TestQueueEdgeCases:
def test_batch_boundary_1000_records(self, fixture_1k):
reader = MARCReader(io.BytesIO(fixture_1k))
records = list(reader)
assert len(records) == 1000
with pytest.raises(StopIteration):
next(reader)
def test_batch_boundary_10000_records(self, fixture_10k):
reader = MARCReader(io.BytesIO(fixture_10k))
records = list(reader)
assert len(records) == 10000
def test_batch_boundary_10000_records_alt(self, fixture_10k):
reader = MARCReader(io.BytesIO(fixture_10k))
records = list(reader)
assert len(records) == 10000
def test_queue_empty_check(self, fixture_1k):
reader = MARCReader(io.BytesIO(fixture_1k))
count = 0
for rec in reader:
count += 1
assert rec is not None
assert count == 1000