def test_missing_entries(self): """ Tests that missing title entries are replaced with None. :return: None """ title = Title({TitleType.ROMAJI: "Shingeki no Kyojin"}) self.assertEqual(title.get(TitleType.ROMAJI), "Shingeki no Kyojin") self.assertEqual(title.get(TitleType.ENGLISH), None) self.assertEqual(title.get(TitleType.JAPANESE), None)
def test_string_representation(self): """ Tests that the string representation is correct :return: None """ title = Title({TitleType.ROMAJI: "SnK", TitleType.ENGLISH: "AoT"}) representation = str(title) serialised = json.loads(representation) self.assertEqual(title, title.deserialize(serialised))
def test_changing_default_title_type(self): """ Tests changing the default title type :return: None """ title = Title({ TitleType.ENGLISH: "Attack on Titan", TitleType.ROMAJI: "Shingeki no Kyojin" }) self.assertEqual(title.default, TitleType.ROMAJI) title.change_default_title_type(TitleType.ENGLISH) self.assertEqual(title.default, TitleType.ENGLISH)
def test_deserialization(self): """ Tests deserializing an ID object :return: None """ data = {"ROMAJI": "SnK", "ENGLISH": "AoT", "default": "ENGLISH"} self.assertEqual( Title.deserialize(data), Title( {TitleType.ROMAJI: "SnK", TitleType.ENGLISH: "AoT"}, default=TitleType.ENGLISH ) )
def test_changing_default_invalid_title_type(self): """ Tests changing the default title type with an invalid title type :return: None """ title = Title({ TitleType.ENGLISH: "Attack on Titan", TitleType.ROMAJI: "Shingeki no Kyojin" }) try: title.change_default_title_type(TitleType.JAPANESE) self.fail() except ValueError: pass
def test_setting_titles_with_invalid_types(self): """ Tests that invalid types in title setting parameters raise a TypeError :return: None """ title = Title({TitleType.ROMAJI: "Shingeki no Kyojin"}) for value in [None, 1, 1.1, True]: try: # noinspection PyTypeChecker title.set(value, TitleType.ROMAJI) self.fail() except TypeError: pass
def test_automatically_using_different_default_title_type(self): """ Tests changing the default title type by not supplying the default title type. :return: None """ title = Title({ TitleType.ENGLISH: "Attack on Titan", TitleType.JAPANESE: "進撃の巨人" }) self.assertEqual(title.default, TitleType.ENGLISH) title = Title({ TitleType.JAPANESE: "進撃の巨人" }) self.assertEqual(title.default, TitleType.JAPANESE)
def _get_common_deserialized_components( cls, data: Dict[str, Optional[str or int or float or bool or Dict or List or Tuple or Set]]) \ -> Dict[str, Optional[str or int or float or bool or Dict or List or Tuple or Set]]: """ Deserializes the common child components of the data dictionary :param data: The data to deserialize :return: The deserialized dictionary """ deserialized = { "media_type": MediaType[data["media_type"]], "id": Id.deserialize(data["id"]), "title": Title.deserialize(data["title"]), "relations": list(map(lambda x: Relation.deserialize(x), data["relations"])), "releasing_status": ReleasingStatus[data["releasing_status"]], "cover_url": data["cover_url"] } for date in ["releasing_start", "releasing_end"]: date_data = data[date] if date_data is not None: deserialized[date] = Date.deserialize(date_data) else: deserialized[date] = None return deserialized
def test_generating_anime_media_list_entry(self): """ Tests generating an anime media list entry object :return: None """ data = self.generate_sample_anime_entry() self.assertEqual(data.id, Id({IdType.MYANIMELIST: 1})) self.assertEqual(data.title, Title({TitleType.ROMAJI: "Test"})) self.assertEqual(data.relations, [ Relation(Id({IdType.MYANIMELIST: 1}), MediaType.ANIME, Id({IdType.MYANIMELIST: 2}), MediaType.MANGA, RelationType.SEQUEL) ]) self.assertEqual(data.releasing_status, ReleasingStatus.FINISHED) self.assertEqual(data.releasing_start, Date(2018, 1, 1)) self.assertEqual(data.releasing_end, Date(2018, 4, 4)) self.assertEqual(data.episode_count, 12) self.assertEqual(data.episode_duration, 25) self.assertEqual(data.cover_url, "https://example.com/image.png") self.assertEqual(data.username, "namboy94") self.assertEqual(data.score, Score(55, ScoreType.PERCENTAGE)) self.assertEqual(data.consuming_status, ConsumingStatus.COMPLETED) self.assertEqual(data.episode_progress, 12) self.assertEqual(data.consuming_start, Date(2018, 1, 1)) self.assertEqual(data.consuming_end, Date(2018, 4, 4)) self.assertEqual(data.media_type, MediaType.ANIME)
def test_serialization(self): """ Tests serializing an ID object :return: None """ ob = Title({TitleType.ROMAJI: "SnK", TitleType.ENGLISH: "AoT"}) data = ob.serialize() self.assertEqual( data, { "ROMAJI": "SnK", "ENGLISH": "AoT", "JAPANESE": None, "default": "ROMAJI" } )
def test_no_entries(self): """ Tests that at least on title is required during initialization :return: None """ try: Title({}) self.fail() except ValueError: pass
def test_different_default_title_type(self): """ Tests using a different title type :return: None """ title = Title({ TitleType.ENGLISH: "Attack on Titan", TitleType.ROMAJI: "Shingeki no Kyojin" }, default=TitleType.ENGLISH) self.assertEqual(title.default, TitleType.ENGLISH)
def test_invalid_deserialization(self): """ Tests that invalid serialized data raises ValueErrors when deserialized :return: None """ for data in [ {"A": 1}, {"ROMAJI": "Hello"}, {"ANILIST": "1", "default": "ROMAJI"}, {"ROMAJI": 1, "default": "ROMAJI"}, {"ROMAJI": None, "default": "ROMAJI"}, {"Romaji": "Hello", "default": "ROMAJI"}, [] ]: try: Title.deserialize(data) self.fail() except (TypeError, ValueError): pass
def generate_sample_manga_data() -> MangaData: """ Generates a generic MangaData object :return: The generated manga data object """ return MangaData(Id( {IdType.MYANIMELIST: 1}), Title({TitleType.ROMAJI: "Test"}), [ Relation(Id({IdType.MYANIMELIST: 1}), MediaType.MANGA, Id({IdType.MYANIMELIST: 2}), MediaType.MANGA, RelationType.SEQUEL) ], ReleasingStatus.FINISHED, Date(2018, 1, 1), Date(2018, 4, 4), "https://example.com/image.png", 100, 10)
def test_invalid_constructor_parameters(self): """ Tests using invalid parameter types with the constructor :return: None """ for parameters in [ (True,), (None,), ({}, 1), ({}, None) ]: try: Title(*parameters) self.fail() except TypeError: pass
def test_generating_manga_data(self): """ Tests generating a manga data object :return: None """ data = self.generate_sample_manga_data() self.assertEqual(data.id, Id({IdType.MYANIMELIST: 1})) self.assertEqual(data.title, Title({TitleType.ROMAJI: "Test"})) self.assertEqual(data.relations, [ Relation(Id({IdType.MYANIMELIST: 1}), MediaType.MANGA, Id({IdType.MYANIMELIST: 2}), MediaType.MANGA, RelationType.SEQUEL) ]) self.assertEqual(data.releasing_status, ReleasingStatus.FINISHED) self.assertEqual(data.releasing_start, Date(2018, 1, 1)) self.assertEqual(data.releasing_end, Date(2018, 4, 4)) self.assertEqual(data.chapter_count, 100) self.assertEqual(data.volume_count, 10) self.assertEqual(data.cover_url, "https://example.com/image.png") self.assertEqual(data.media_type, MediaType.MANGA)
def test_title_construction(self): """ Tests constructing the title :return: None """ title = Title({ TitleType.ROMAJI: "Shingeki no Kyojin", TitleType.ENGLISH: "Attack on Titan", TitleType.JAPANESE: "進撃の巨人" }) # Default = ROMAJI self.assertEqual(title.get(), "Shingeki no Kyojin") self.assertEqual(title.get(TitleType.ENGLISH), "Attack on Titan") self.assertEqual(title.get(TitleType.ROMAJI), "Shingeki no Kyojin") self.assertEqual(title.get(TitleType.JAPANESE), "進撃の巨人")
def test_equality(self): """ Tests that the equality of the objects is handled correctly :return: None """ one = Title({TitleType.ROMAJI: "SnK", TitleType.ENGLISH: "AoT"}) two = Title({TitleType.ROMAJI: "SnK", TitleType.ENGLISH: "AoT"}) three = Title({TitleType.ROMAJI: "SnK", TitleType.ENGLISH: "AoT"}, default=TitleType.ENGLISH) four = Title({TitleType.ENGLISH: "AoT"}) self.assertEqual(one, two) self.assertNotEqual(two, three) self.assertNotEqual(two, four) self.assertNotEqual(three, four) three.change_default_title_type(TitleType.ROMAJI) self.assertEqual(two, three) self.assertNotEqual(three, four) self.assertNotEqual(one, "Test")
def generate_sample_serialized_anime_data() -> \ Dict[str, Optional[str or int or float or bool or Dict or List or Tuple or Set]]: """ Generates some sample serialized anime data :return: The serialized sample data """ return { "media_type": "ANIME", "id": Id({ IdType.MYANIMELIST: 1 }).serialize(), "title": Title({ TitleType.ROMAJI: "Test" }).serialize(), "relations": [ Relation(Id({IdType.MYANIMELIST: 1}), MediaType.ANIME, Id({IdType.MYANIMELIST: 2}), MediaType.MANGA, RelationType.SEQUEL).serialize() ], "releasing_status": ReleasingStatus.FINISHED.name, "releasing_start": Date(2018, 1, 1).serialize(), "releasing_end": Date(2018, 4, 4).serialize(), "episode_count": 12, "episode_duration": 25, "cover_url": "https://example.com/image.png" }
def __generate_media_data(media_type: MediaType, data: Dict[str, Any]) -> MediaData: """ Generates an MediaData object from a GraphQL result :param media_type: The media type to generate :param data: The data to convert into an AnimeData object :return: The generated AnimeData object """ _id = Id({ IdType.ANILIST: data["id"], IdType.MYANIMELIST: data["idMal"] }) title = Title({ TitleType.ROMAJI: data["title"]["romaji"], TitleType.ENGLISH: data["title"]["english"], TitleType.JAPANESE: data["title"]["native"], }) if title.get(TitleType.ENGLISH) is None: title.set(title.get(TitleType.ROMAJI), TitleType.ENGLISH) relations = [] for relation in data["relations"]["edges"]: dest_id = Id({ IdType.ANILIST: relation["node"]["id"], IdType.MYANIMELIST: relation["node"]["idMal"] }) dest_media_type = media_type rel_type = RelationType[relation["relationType"]] if rel_type == RelationType.ADAPTATION: if media_type == MediaType.ANIME: dest_media_type = MediaType.MANGA else: dest_media_type = MediaType.ANIME relations.append( Relation(_id, media_type, dest_id, dest_media_type, rel_type).serialize()) releasing_status = \ data["status"].replace("NOT_YET_RELEASED", "NOT_RELEASED") serialized = { "media_type": media_type.name, "id": _id.serialize(), "title": title.serialize(), "relations": relations, "releasing_status": releasing_status, "cover_url": data["coverImage"]["large"], "episode_count": data["episodes"], "episode_duration": data["duration"], "chapter_count": data["episodes"], "volume_count": data["episodes"] } for api_key, dict_key in { "startDate": "releasing_start", "endDate": "releasing_end" }.items(): try: serialized[dict_key] = Date(data[api_key]["year"], data[api_key]["month"], data[api_key]["day"]).serialize() except (TypeError, ValueError): serialized[dict_key] = None return MediaData.deserialize(serialized)
def test_setting_titles(self): """ Tests manually setting title values :return: None """ title = Title({TitleType.ROMAJI: "Shingeki no Kyojin"}) self.assertEqual(title.get(TitleType.ROMAJI), "Shingeki no Kyojin") self.assertEqual(title.get(TitleType.ENGLISH), None) self.assertEqual(title.get(TitleType.JAPANESE), None) title.set("Attack on Titan", TitleType.ENGLISH) title.set("進撃の巨人", TitleType.JAPANESE) self.assertEqual(title.get(TitleType.ENGLISH), "Attack on Titan") self.assertEqual(title.get(TitleType.ROMAJI), "Shingeki no Kyojin") self.assertEqual(title.get(TitleType.JAPANESE), "進撃の巨人") title.set("AAAAA", TitleType.ROMAJI) self.assertEqual(title.get(), "AAAAA")