"""Tests for Mahjong Puzzle questions generation""" import string import pytest from reasoning_gym.games.mahjong import MahjongPuzzleConfig, MahjongPuzzleCurriculum, MahjongPuzzleDataset def test_mahjong_puzzle_config_validation(): """Test that invalid configs raise appropriate errors""" with pytest.raises(AssertionError): config = MahjongPuzzleConfig(min_num_rounds=-1) # Negative not allowed config.validate() with pytest.raises(AssertionError): config = MahjongPuzzleConfig(min_num_rounds=0) # Zero not allowed config.validate() with pytest.raises(AssertionError): config = MahjongPuzzleConfig(min_num_rounds=3, max_num_rounds=2) # Min > Max config.validate() def test_mahjong_puzzle_dataset_deterministic(): """Test that dataset generates same items with same seed""" config = MahjongPuzzleConfig(seed=42, size=10) dataset1 = MahjongPuzzleDataset(config) dataset2 = MahjongPuzzleDataset(config) for i in range(len(dataset1)): assert dataset1[i] == dataset2[i] def test_mahjong_puzzle_dataset_items(): """Test basic properties of generated items""" config = MahjongPuzzleConfig(min_num_rounds=3, max_num_rounds=5, size=10, seed=42) dataset = MahjongPuzzleDataset(config) for i in range(len(dataset)): item = dataset[i] # Check item structure assert isinstance(item, dict) assert "question" in item assert "answer" in item assert "metadata" in item # Check metadata assert "rounds" in item["metadata"] assert "solution" in item["metadata"] rounds = item["metadata"]["rounds"] solution = item["metadata"]["solution"] # Verify values assert solution in ["Peng", "Chi", "Pass"] assert 3 <= len(rounds) <= 5 assert all(isinstance(r, dict) for r in rounds) assert all("add" in r for r in rounds) assert all("remove" in r for r in rounds) assert all(len(r["cards"]) == 13 for r in rounds) assert all(r["result"] in ["Peng", "Chi", "Pass"] for r in rounds) def test_mahjong_puzzle_dataset_iteration(): """Test that iteration respects dataset size""" config = MahjongPuzzleConfig(size=5, seed=42) dataset = MahjongPuzzleDataset(config) items = list(dataset) assert len(items) == config.size # Test multiple iterations yield same items assert items == list(dataset) def test_mahjong_puzzle_answer(): """Test the _get_answer method""" config = MahjongPuzzleConfig(seed=42) dataset = MahjongPuzzleDataset(config) # Peng cards = "ABBCCDDEEFFGH" assert dataset._check_peng(cards, new_card="B") == True # B, B, B assert dataset._check_peng(cards, new_card="A") == False # Chi cards = "ABDGIKMOQSUWY" assert dataset._check_chi(cards, new_card="C") == True # A, B, C assert dataset._check_chi(cards, new_card="A") == False # Pass cards = "ACEGIKMOQSUWY" for c in string.ascii_lowercase: assert dataset._check_peng(cards, new_card=c) == False assert dataset._check_chi(cards, new_card=c) == False def test_mahjong_puzzle_curriculum(): curriculum = MahjongPuzzleCurriculum() base_value = {"size": 150, "seed": 1} base_cfg: MahjongPuzzleConfig = curriculum.generate_configuration(base_value) assert base_cfg.seed == 1 assert base_cfg.size == 150 assert base_cfg.min_num_rounds == 10 and base_cfg.max_num_rounds == 10 # test incrementing attribute levels for num_rounds attribute curriculum.increment_attr_level("num_rounds") increased_cfg = curriculum.generate_configuration(base_value) assert increased_cfg.min_num_rounds == 10 and increased_cfg.max_num_rounds == 50 # test incrementing again curriculum.increment_attr_level("num_rounds") increased_cfg = curriculum.generate_configuration(base_value) assert increased_cfg.min_num_rounds == 10 and increased_cfg.max_num_rounds == 100