from __future__ import annotations import sys import unittest from pathlib import Path import pandas as pd REPO_ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(REPO_ROOT / "src")) from climbingboardgpt.config import BoardConfig from climbingboardgpt.evaluation import nearest_real_route_same_board from climbingboardgpt.generation import validity_summary from climbingboardgpt.grades import to_grouped_v from climbingboardgpt.tokenization import ( parse_frames, parse_tokens, tokenize_route, tokens_to_hold_records, ) class CoreBehaviorTest(unittest.TestCase): def test_to_grouped_v_clamps_and_maps_display_difficulty(self): self.assertEqual(to_grouped_v(10), 0) self.assertEqual(to_grouped_v(22), 6) self.assertEqual(to_grouped_v(99), 16) def test_parse_frames_extracts_placement_role_pairs(self): self.assertEqual(parse_frames("p344r5p369r6p603r7"), [(344, 5), (369, 6), (603, 7)]) self.assertEqual(parse_frames(None), []) def test_shared_token_parser_handles_repr_and_sequence_strings(self): self.assertEqual(parse_tokens("['', '']"), ["", ""]) self.assertEqual(parse_tokens(" "), ["", ""]) def test_tokens_to_hold_records_extracts_shared_shape(self): records = tokens_to_hold_records(["", "", ""]) self.assertEqual( records, [ { "token": "", "board_token_prefix": "TB2", "board_prefix": "TB2", "placement_id": 344, "role": "start", }, { "token": "", "board_token_prefix": "TB2", "board_prefix": "TB2", "placement_id": 603, "role": "finish", }, ], ) def test_validity_summary_flags_basic_valid_route(self): summary = validity_summary( ["", "", ""], requested_board_prefix="TB2", ) self.assertTrue(summary["basic_valid"]) self.assertEqual(summary["n_hold_tokens"], 3) def test_tokenize_route_uses_canonical_hold_order(self): config = BoardConfig( board_key="tb2", display_name="TB2", token_prefix="TB2", db_path=Path("unused.db"), layout_id=1, max_angle=None, min_fa_date=None, placement_y_max=None, include_mirror_placement_id=False, role_definitions={"start": 5, "middle": 6, "finish": 7, "foot": 8}, ) placement_lookup = { ("tb2", 603): {"x": 0, "y": 120}, ("tb2", 344): {"x": 0, "y": 10}, ("tb2", 369): {"x": 0, "y": 80}, } row = { "frames": "p603r7p369r6p344r5", "angle": 40, "display_difficulty": 22, } self.assertEqual( tokenize_route(row, config, placement_lookup), [ "", "", "", "", "", "", "", "", ], ) def test_nearest_real_route_same_board_finds_best_jaccard_match(self): real_df = pd.DataFrame( [ { "board_key": "tb2", "hold_set": frozenset({1, 2, 3}), "uuid": "a", "climb_name": "close", "grouped_v": 5, "angle": 40, }, { "board_key": "tb2", "hold_set": frozenset({7, 8}), "uuid": "b", "climb_name": "far", "grouped_v": 8, "angle": 45, }, ] ) result = nearest_real_route_same_board(frozenset({1, 2, 4}), "tb2", real_df) self.assertEqual(result["nearest_real_uuid"], "a") self.assertAlmostEqual(result["nearest_real_jaccard"], 0.5) if __name__ == "__main__": unittest.main()