59 lines
2 KiB
Python
59 lines
2 KiB
Python
|
|
from mdgrep.snippets import ELLIPSIS, segments
|
||
|
|
|
||
|
|
|
||
|
|
def join(segs):
|
||
|
|
return "".join(s["t"] for s in segs)
|
||
|
|
|
||
|
|
|
||
|
|
def test_short_text_full_with_hits():
|
||
|
|
segs = segments("hello world", [(6, 11)])
|
||
|
|
assert segs == [{"t": "hello ", "hit": False}, {"t": "world", "hit": True}]
|
||
|
|
|
||
|
|
|
||
|
|
def test_no_spans_returns_whole_text():
|
||
|
|
assert segments("abc", []) == [{"t": "abc", "hit": False}]
|
||
|
|
|
||
|
|
|
||
|
|
def test_long_text_windowed_around_hit():
|
||
|
|
text = " ".join(f"w{i}" for i in range(400))
|
||
|
|
hit_start = text.index("w200")
|
||
|
|
segs = segments(text, [(hit_start, hit_start + 4)], max_chars=100, context=30)
|
||
|
|
assert segs[0]["t"] == ELLIPSIS and segs[-1]["t"] == ELLIPSIS
|
||
|
|
assert any(s["hit"] and s["t"] == "w200" for s in segs)
|
||
|
|
assert len(join(segs)) < 150
|
||
|
|
|
||
|
|
|
||
|
|
def test_windows_snap_to_word_boundaries():
|
||
|
|
text = "alpha beta gamma delta epsilon zeta eta theta iota kappa lambda"
|
||
|
|
start = text.index("epsilon")
|
||
|
|
segs = segments(text, [(start, start + 7)], max_chars=20, context=8)
|
||
|
|
inner = join(s for s in segs if s["t"] != ELLIPSIS)
|
||
|
|
assert not inner.startswith("lta") and inner.split()[0] in ("gamma", "delta")
|
||
|
|
|
||
|
|
|
||
|
|
def test_multiple_hits_separate_windows():
|
||
|
|
text = "x " * 300 + "foo " + "y " * 300 + "bar " + "z " * 300
|
||
|
|
f, b = text.index("foo"), text.index("bar")
|
||
|
|
segs = segments(text, [(f, f + 3), (b, b + 3)], max_chars=200, context=20)
|
||
|
|
hits = [s["t"] for s in segs if s["hit"]]
|
||
|
|
assert hits == ["foo", "bar"]
|
||
|
|
assert sum(1 for s in segs if s["t"] == ELLIPSIS) == 3
|
||
|
|
|
||
|
|
|
||
|
|
def test_budget_limits_windows_but_keeps_first_hit():
|
||
|
|
text = ("filler " * 50 + "hit ") * 10
|
||
|
|
spans = []
|
||
|
|
pos = 0
|
||
|
|
while (i := text.find("hit", pos)) != -1:
|
||
|
|
spans.append((i, i + 3))
|
||
|
|
pos = i + 3
|
||
|
|
segs = segments(text, spans, max_chars=60, context=20)
|
||
|
|
assert sum(1 for s in segs if s["hit"]) >= 1
|
||
|
|
assert len(join(segs)) < 200
|
||
|
|
|
||
|
|
|
||
|
|
def test_no_hits_long_text_shows_beginning():
|
||
|
|
text = "start " + "word " * 200
|
||
|
|
segs = segments(text, [], max_chars=50)
|
||
|
|
assert segs[0]["t"].startswith("start")
|
||
|
|
assert segs[-1]["t"] == ELLIPSIS
|