Merge branch 'master' into circleci-hook

This commit is contained in:
Alessandro Pezzè 2020-04-30 23:59:04 +02:00 committed by GitHub
commit 5b8e4e1964
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 126 additions and 35 deletions

View file

@ -3134,45 +3134,75 @@ class EvolutionChainDetailSerializer(serializers.ModelSerializer):
pokemon_objects, many=True, context=self.context
).data
chain = entry = OrderedDict()
current_evolutions = None
evolution_data = None
previous_entry = None
previous_species = None
# convert evolution data list to tree
evolution_tree = self.build_evolution_tree(ref_data)
for index, species in enumerate(ref_data):
# If evolves from something
if species["evolves_from_species"]:
# In case this pokemon is one of multiple evolutions a pokemon can make
if previous_species:
if previous_species["id"] == species["evolves_from_species"]:
current_evolutions = previous_entry["evolves_to"]
entry = OrderedDict()
evolution_object = PokemonEvolution.objects.filter(
evolved_species=species["id"]
)
evolution_data = PokemonEvolutionSerializer(
evolution_object, many=True, context=self.context
).data
current_evolutions.append(entry)
entry["is_baby"] = species["is_baby"]
entry["species"] = summary_data[index]
entry["evolution_details"] = evolution_data or []
entry["evolves_to"] = []
# Keep track of previous entries for complex chaining
previous_entry = entry
previous_species = species
# serialize chain recursively from tree
chain = self.build_chain_link_entry(evolution_tree, summary_data)
return chain
# converts a list of Pokemon species evolution data into a tree representing the evolution chain
def build_evolution_tree(self, species_evolution_data):
evolution_tree = OrderedDict()
evolution_tree["species"] = species_evolution_data[0]
evolution_tree["children"] = []
for species in species_evolution_data[1:]:
chain_link = OrderedDict()
chain_link["species"] = species
chain_link["children"] = []
evolves_from_species_id = chain_link["species"]["evolves_from_species"]
# find parent link by DFS
parent_link = evolution_tree
search_stack = [parent_link]
while len(search_stack) > 0:
l = search_stack.pop()
if l["species"]["id"] == evolves_from_species_id:
parent_link = l
break
# "left" to "right" requires reversing the list of children
search_stack += reversed(l["children"])
parent_link["children"].append(chain_link)
return evolution_tree
# serializes an evolution chain link recursively
# chain_link is a tree representing an evolution chain
def build_chain_link_entry(self, chain_link, summary_data):
entry = OrderedDict()
evolution_data = None
species = chain_link["species"]
if species["evolves_from_species"]:
evolution_object = PokemonEvolution.objects.filter(
evolved_species=species["id"]
)
evolution_data = PokemonEvolutionSerializer(
evolution_object, many=True, context=self.context
).data
entry["is_baby"] = species["is_baby"]
species_summary = next(x for x in summary_data if x["name"] == species["name"])
entry["species"] = species_summary
entry["evolution_details"] = evolution_data or []
evolves_to = [
self.build_chain_link_entry(c, summary_data) for c in chain_link["children"]
]
entry["evolves_to"] = evolves_to
return entry
class PokemonDexNumberSerializer(serializers.ModelSerializer):

View file

@ -5203,6 +5203,67 @@ class APITests(APIData, APITestCase):
"{}{}/type/{}/".format(TEST_HOST, API_V2, stage_two_second_party_type.pk),
)
# verifies that the wurmple evolution chain is serialized correctly
def test_evolution_chain_api_wurmple_bugfix(self):
# set up wurmple-like evolution chain
evolution_chain = self.setup_evolution_chain_data()
basic = self.setup_pokemon_species_data(
name="wurmple", evolution_chain=evolution_chain,
)
stage_one_first = self.setup_pokemon_species_data(
name="silcoon", evolves_from_species=basic, evolution_chain=evolution_chain,
)
stage_one_first_evolution = self.setup_pokemon_evolution_data(
evolved_species=stage_one_first, min_level=7
)
stage_two_first = self.setup_pokemon_species_data(
name="beautifly",
evolves_from_species=stage_one_first,
evolution_chain=evolution_chain,
)
stage_two_first_evolution = self.setup_pokemon_evolution_data(
evolved_species=stage_two_first, min_level=10
)
stage_one_second = self.setup_pokemon_species_data(
name="cascoon", evolves_from_species=basic, evolution_chain=evolution_chain,
)
stage_one_second_evolution = self.setup_pokemon_evolution_data(
evolved_species=stage_one_second, min_level=7
)
stage_two_second = self.setup_pokemon_species_data(
name="dustox",
evolves_from_species=stage_one_second,
evolution_chain=evolution_chain,
)
stage_two_second_evolution = self.setup_pokemon_evolution_data(
evolved_species=stage_two_second, min_level=10
)
response = self.client.get(
"{}/evolution-chain/{}/".format(API_V2, evolution_chain.pk)
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
# base params
self.assertEqual(response.data["id"], evolution_chain.pk)
# assert tree has been serialized correctly
basic_data = response.data["chain"]
self.assertEqual(len(basic_data["evolves_to"]), 2)
stage_one_first_data = basic_data["evolves_to"][0]
self.assertEqual(len(stage_one_first_data["evolves_to"]), 1)
stage_one_second_data = basic_data["evolves_to"][1]
self.assertEqual(len(stage_one_second_data["evolves_to"]), 1)
# Encounter Tests
def test_encounter_method_api(self):