File size: 2,789 Bytes
3e67073
 
 
 
 
 
 
 
 
 
 
 
45ade5d
3e67073
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45ade5d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3e67073
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
"""Tests for MathVision-style dataset loading."""

from __future__ import annotations

import json
from pathlib import Path

import pytest

from mathvision_explorer.dataset import (
    filter_records,
    load_jsonl_records,
    load_jsonl_records_from_text,
    record_from_mapping,
    summarize_records,
)


def test_record_from_mapping_accepts_problem_id_fallback() -> None:
    """Raw records may use either id or problem_id for the stable key."""

    record = record_from_mapping(
        {
            "problem_id": "mv-1",
            "question": "How many squares are visible?",
            "answer": "4",
            "options": ["3", "4", "5"],
            "subject": "geometry",
            "level": 2,
        }
    )

    assert record.problem_id == "mv-1"
    assert record.options == ("3", "4", "5")
    assert record.subject == "geometry"
    assert record.level == 2


def test_load_jsonl_records_resolves_relative_image_paths(tmp_path: Path) -> None:
    """Relative image paths are resolved from the JSONL file directory."""

    jsonl_path = tmp_path / "records.jsonl"
    payload = {
        "id": "mv-2",
        "question": "Pick the matching pattern.",
        "answer": "B",
        "image": "images/mv-2.png",
    }
    jsonl_path.write_text(json.dumps(payload) + "\n", encoding="utf-8")

    records = load_jsonl_records(jsonl_path)

    assert records[0].image_path == tmp_path / "images" / "mv-2.png"


def test_load_jsonl_records_from_text_resolves_relative_image_paths(tmp_path: Path) -> None:
    """Uploaded JSONL content can still use a caller-provided image base directory."""

    payload = {
        "id": "mv-3",
        "question": "Pick the matching graph.",
        "answer": "A",
        "image": "images/mv-3.png",
    }

    records = load_jsonl_records_from_text(json.dumps(payload), source_dir=tmp_path)

    assert records[0].image_path == tmp_path / "images" / "mv-3.png"


def test_filter_and_summary() -> None:
    """Records can be filtered and summarized for explorer views."""

    records = [
        record_from_mapping({"id": "a", "question": "Q1", "answer": "1", "subject": "counting"}),
        record_from_mapping(
            {"id": "b", "question": "Q2", "answer": "2", "subject": "geometry", "level": 3}
        ),
    ]

    assert [record.problem_id for record in filter_records(records, subject="geometry")] == ["b"]
    assert summarize_records(records) == {
        "records": 2,
        "images": 0,
        "subjects": ["counting", "geometry"],
        "levels": [3],
    }


def test_invalid_options_raise_value_error() -> None:
    """Options must be textual choices."""

    with pytest.raises(ValueError, match="Options"):
        record_from_mapping({"id": "bad", "question": "Q", "answer": "A", "options": [1]})