import pytest from multiplayer_crosswords.dictionary import Word, Dictionary def test_add_word_and_to_dict(): d = Dictionary() w = Word("apple", ["a red or green fruit"], 0.2) d.add_word(w) result = d.to_dict() assert "words" in result assert len(result["words"]) == 1 assert result["words"][0]["word"] == "apple" assert result["words"][0]["hints"] == ["a red or green fruit"] assert result["words"][0]["difficulty"] == 0.2 def test_from_dict_and_to_dict_roundtrip(): data = { "words": [ {"word": "banana", "hints": ["a yellow fruit", "something monkeys like to eat"], "difficulty": 0.1}, {"word": "car", "hints": ["vehicle", "four wheels"], "difficulty": 0.3} ] } d = Dictionary.from_dict(data) assert len(d.words) == 2 assert d.words[0].word == "banana" assert d.words[1].hints == ["vehicle", "four wheels"] assert d.words[1].difficulty == 0.3 assert d.to_dict() == data def test_to_json_and_from_json(): d = Dictionary() d.add_word(Word("dog", ["animal", "barks"], 0.15)) json_str = d.to_json() d2 = Dictionary.from_json(json_str) assert len(d2.words) == 1 assert d2.words[0].word == "dog" assert d2.words[0].hints == ["animal", "barks"] assert d2.words[0].difficulty == 0.15 def test_empty_dictionary_to_dict_and_json(): d = Dictionary() assert d.to_dict() == {"words": []} json_str = d.to_json() assert json_str.strip().startswith("{") d2 = Dictionary.from_json(json_str) assert isinstance(d2, Dictionary) assert d2.words == [] def test_word_to_dict_and_from_dict(): w = Word("cat", ["animal", "meows"], 0.12) d = w.to_dict() assert d == {"word": "cat", "hints": ["animal", "meows"], "difficulty": 0.12} w2 = Word.from_dict(d) assert w2.word == "cat" assert w2.hints == ["animal", "meows"] assert w2.difficulty == 0.12 def test_find_by_pattern_exact_match(): d = Dictionary() d.add_word(Word("apple", ["fruit"], 0.2)) d.add_word(Word("apply", ["verb"], 0.3)) d.add_word(Word("angle", ["geometry"], 0.4)) result = d.find_by_pattern("apple") assert [r.word for r in result] == ["apple"] def test_find_by_pattern_with_wildcards(): d = Dictionary() d.add_word(Word("apple", ["fruit"], 0.2)) d.add_word(Word("apply", ["verb"], 0.3)) d.add_word(Word("angle", ["geometry"], 0.4)) d.add_word(Word("ample", ["enough"], 0.5)) # Pattern: a**le should match apple and angle and ample result = sorted([w.word for w in d.find_by_pattern("a**le")]) assert set(result) == {"apple", "angle", "ample"} def test_find_by_pattern_all_wildcards(): d = Dictionary() d.add_word(Word("apple", ["fruit"], 0.2)) d.add_word(Word("apply", ["verb"], 0.3)) d.add_word(Word("angle", ["geometry"], 0.4)) # Pattern: ***** should match all 5-letter words result = sorted([w.word for w in d.find_by_pattern("*****")]) assert set(result) == {"apple", "apply", "angle"} def test_find_by_pattern_no_match(): d = Dictionary() d.add_word(Word("apple", ["fruit"], 0.2)) d.add_word(Word("apply", ["verb"], 0.3)) # Pattern: z**** should match nothing result = d.find_by_pattern("z****") assert list(result) == [] def test_find_by_pattern_duplicate_letters(): d = Dictionary() d.add_word(Word("level", ["word"], 0.1)) d.add_word(Word("lever", ["tool"], 0.2)) # Pattern: l*vel should match "level" only result = d.find_by_pattern("l*vel") assert [r.word for r in result] == ["level"] def test_find_by_pattern_length_not_in_index(): d = Dictionary() d.add_word(Word("cat", ["animal"], 0.1)) # Pattern: four letters, but only 3-letter word in dict result = d.find_by_pattern("****") assert [r.word for r in result] == []