e93507a09c
Lockfile supply-chain audit / lockfile supply-chain audit (push) Has been cancelled
Windows Studio GGUF CI / GPU prebuilt resolves without Visual Studio (push) Has been cancelled
Windows Studio GGUF CI / setup.ps1 unit tests (VS 2026 / CMake guard) (push) Has been cancelled
Windows Studio GGUF CI / real-VS detection (VS 2022) (push) Has been cancelled
Windows Studio GGUF CI / real-VS detection (VS 2026) (push) Has been cancelled
Windows Studio GGUF CI / VC++ runtime detect + install round-trip (windows-2025-vs2026) (push) Has been cancelled
Windows Studio GGUF CI / VC++ runtime detect + install round-trip (windows-latest) (push) Has been cancelled
Windows Studio Update CI / Studio Updating Tests (push) Has been cancelled
Wheel CI / Wheel build + content sanity + import smoke (push) Has been cancelled
Lint CI / Source lint (Python + shell + YAML + JSON + safety nets) (push) Has been cancelled
MLX CI on Mac M1 / dispatch (push) Has been cancelled
Security audit / advisory audit (pip + npm + cargo) (push) Has been cancelled
Security audit / pip scan-packages :: extras (push) Has been cancelled
Security audit / pip scan-packages :: studio (push) Has been cancelled
Security audit / pip scan-packages :: hf-stack (push) Has been cancelled
Security audit / npm scan-packages (Studio frontend tarballs) (push) Has been cancelled
Security audit / workflow-trigger lint (pull_request_target / cache-poisoning) (push) Has been cancelled
Security audit / pytest tests/security (push) Has been cancelled
Security audit / npm provenance + new install-script diff (push) Has been cancelled
Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Backend CI / (Python 3.10) (push) Has been cancelled
Backend CI / (Python 3.11) (push) Has been cancelled
Backend CI / (Python 3.12) (push) Has been cancelled
Backend CI / (Python 3.13) (push) Has been cancelled
Backend CI / Repo tests (CPU) (push) Has been cancelled
Frontend CI / Frontend build + bundle sanity (push) Has been cancelled
Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Studio GGUF CI / JSON, images (push) Has been cancelled
Mac Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Mac Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Mac Studio GGUF CI / JSON, images (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-14) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-15) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-26) (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-15-intel) (push) Has been cancelled
Mac Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Mac Studio Install Matrix CI / Install + load (macos-26-intel) (push) Has been cancelled
Mac Studio UI CI / Chat UI Tests (push) Has been cancelled
Studio Tauri CI / Tauri Linux debug build (no codesign) (push) Has been cancelled
Mac Studio Update CI / Studio Updating Tests (push) Has been cancelled
Studio UI CI / Chat UI Tests (push) Has been cancelled
Windows Studio API CI / Studio API & Auth Tests (push) Has been cancelled
Windows Studio UI CI / Chat UI Tests (push) Has been cancelled
Studio Update CI / Studio Updating Tests (push) Has been cancelled
Core / Core (HF=default + TRL=default) (push) Has been cancelled
Core / Core (HF=4.57.6 + TRL<1) (push) Has been cancelled
Core / Core (HF=latest + TRL=latest) (push) Has been cancelled
Core / llama.cpp build + smoke (push) Has been cancelled
Windows Studio GGUF CI / OpenAI, Anthropic API tests (push) Has been cancelled
Windows Studio GGUF CI / Tool calling Tests (push) Has been cancelled
Windows Studio GGUF CI / JSON, images (push) Has been cancelled
Windows Studio GGUF CI / Studio install + inference without Visual Studio (push) Has been cancelled
Studio export capability / capability (macos-latest) (push) Has been cancelled
Studio export capability / capability (ubuntu-latest) (push) Has been cancelled
Studio export capability / capability (windows-latest) (push) Has been cancelled
Cross-platform parity / parity (macos-latest) (push) Has been cancelled
Cross-platform parity / parity (windows-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
Studio load-orchestrator CI / test (push) Has been cancelled
70 lines
2.8 KiB
Python
70 lines
2.8 KiB
Python
# SPDX-License-Identifier: AGPL-3.0-only
|
|
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
|
|
|
|
"""Chunking unit tests (no DB, no model)."""
|
|
|
|
from core.rag.chunking import chunk_pages
|
|
from core.rag.parsers import Page, parse_text
|
|
|
|
WORDS = lambda t: len(t.split()) # noqa: E731
|
|
|
|
|
|
def _page(text: str, page_number = None) -> Page:
|
|
return Page(text = text, page_number = page_number, char_count = len(text))
|
|
|
|
|
|
def test_chunk_token_bounds_and_overlap():
|
|
text = " ".join(f"w{i}" for i in range(300))
|
|
chunks = chunk_pages([_page(text)], max_tokens = 128, overlap = 24, count = WORDS)
|
|
assert len(chunks) >= 3
|
|
assert all(c.token_count <= 128 for c in chunks)
|
|
a, b = chunks[0].text.split(), chunks[1].text.split()
|
|
shared = next((n for n in range(60, 0, -1) if a[-n:] == b[:n]), 0)
|
|
assert shared == 24 # exactly overlap tokens carried
|
|
|
|
|
|
def test_chunk_never_exceeds_max_with_overlap_carry():
|
|
"""Overlap carry is trimmed so no chunk exceeds max_tokens (else the embedder overflows)."""
|
|
s1 = " ".join("a" for _ in range(10))
|
|
s2 = " ".join("b" for _ in range(95)) # near max
|
|
chunks = chunk_pages([_page(f"{s1}. {s2}")], max_tokens = 100, overlap = 24, count = WORDS)
|
|
assert all(c.token_count <= 100 for c in chunks), [c.token_count for c in chunks]
|
|
|
|
|
|
def test_chunk_indices_are_sequential():
|
|
chunks = chunk_pages([_page("alpha. " * 200)], max_tokens = 32, overlap = 0, count = WORDS)
|
|
assert [c.chunk_index for c in chunks] == list(range(len(chunks)))
|
|
|
|
|
|
def test_chunk_tracks_source_page_index():
|
|
pages = [_page("alpha bravo " * 80, 1), _page("charlie delta " * 80, 2)]
|
|
chunks = chunk_pages(pages, max_tokens = 32, overlap = 0, count = WORDS)
|
|
page0 = [c for c in chunks if c.source_page_index == 0]
|
|
page1 = [c for c in chunks if c.source_page_index == 1]
|
|
assert page0 and page1
|
|
assert all(c.page_number == 1 for c in page0)
|
|
assert all(c.page_number == 2 for c in page1)
|
|
|
|
|
|
def test_chunk_char_offsets_locate_text_in_page():
|
|
# Each chunk's char span must slice back to text containing it.
|
|
page_text = "alpha bravo charlie delta echo foxtrot golf hotel " * 30
|
|
pages = [_page(page_text, 1)]
|
|
chunks = chunk_pages(pages, max_tokens = 16, overlap = 0, count = WORDS)
|
|
assert len(chunks) > 1
|
|
for c in chunks:
|
|
assert 0 <= c.page_char_start < c.page_char_end <= len(page_text)
|
|
sliced = page_text[c.page_char_start : c.page_char_end]
|
|
assert c.text in sliced or sliced.strip() == c.text
|
|
|
|
|
|
def test_empty_page_yields_no_chunks():
|
|
chunks = chunk_pages([_page(" \n ")], max_tokens = 32, overlap = 0, count = WORDS)
|
|
assert chunks == []
|
|
|
|
|
|
def test_parse_text_single_page():
|
|
pages = parse_text("hello world")
|
|
assert len(pages) == 1
|
|
assert pages[0].char_count == len("hello world")
|