# jogai - Python Game Library # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the Free # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Ramón Palleiro Rodríguez # Zero! Factorial Studio # info@zero.gal from os.path import join import pygame import pytest from jogai import paths, settings from jogai import videogame as vg from jogai.character import ( Character, _check_and_format_args_for_group, _load_characters_and_groups, ) from jogai.texts import SpeechBubble from jogai.translations import gettext as _ def test_check_and_format_args_for_a_random_group_with_a_dict(): assert ( _check_and_format_args_for_group('random', {'foo': 'bar'}) == '**arguments' ) def test_check_and_format_args_for_a_rectangle_group_with_a_list(): assert ( _check_and_format_args_for_group('rectangle', [2, 3]) == '*arguments' ) def test_check_and_format_args_for_a_square_group_with_a_integer(): assert _check_and_format_args_for_group('square', 3) == 'arguments' def test_check_and_format_args_for_a_stairs_group_with_a_dict(): assert ( _check_and_format_args_for_group('stairs', {'foo': 'bar'}) == '**arguments' ) def test_check_and_format_args_for_group_with_wrong_args(): group_type = 'rectangle' args_type = list.__name__ with pytest.raises(TypeError) as e: _check_and_format_args_for_group(group_type, 5) assert ( str(e.value) == f'the arguments for the {group_type} group must be {args_type}' ) def test_check_and_format_args_for_unknown_group(): group_type = 'foo' with pytest.raises(TypeError) as e: format = _check_and_format_args_for_group(group_type, 3) assert str(e.value) == f'the group type {group_type} is unknown' def test_load_characters_with_no_characters_key_in_data(): characters = _load_characters_and_groups({}) assert characters == ([], []) def test_load_characters_with_a_correct_filename(): characters = _load_characters_and_groups( {'foo': {'filename': 'protagonist.png'}} ) assert characters[0][0].name == 'foo' assert characters[0][0].image_filename == 'protagonist.png' # def test_load_data_with_none_argument(videogame_test): # ... # protagonist._load_data(None) class TestCharacter: def test_load_data_with_wrong_type(self, videogame_test, character_test): with pytest.raises(TypeError) as e: character_test._load_data('foo') assert str(e.value) == 'the data input must be a dict' def test_height_is_a_non_negative_integer( self, videogame_test, character_test ): assert character_test.height > -1 def test_width_is_a_non_negative_integer( self, videogame_test, character_test ): assert character_test.width > -1 def test_x_coordinate_is_an_integer(self, videogame_test, character_test): assert isinstance(character_test.x, int) def test_y_coordinate_is_an_integer(self, videogame_test, character_test): assert isinstance(character_test.y, int) def test_wrong_character_name(self): with pytest.raises(TypeError) as e: Character('protagonist.png', name=1) assert str(e.value) == 'the character name must be a string' def test_repr_character(self, videogame_test, character_test): assert repr(character_test) == f'Character: {character_test.name}' def test_angle_property(self, videogame_test, character_test): angle = 90 character_test.angle = angle assert character_test.angle == angle def test_bouncy_property(self, videogame_test, character_test): bouncy = True character_test.bouncy = bouncy assert character_test.bouncy == bouncy def test_center_property(self, videogame_test, character_test): assert character_test.center == ( character_test.x + character_test.width // 2, character_test.y + character_test.height // 2, ) def test_collidable_property(self, videogame_test, character_test): collidable = True character_test.collidable = collidable assert character_test.collidable == collidable def test_gravitative_property(self, videogame_test, character_test): gravitative = True character_test.gravitative = gravitative assert character_test.gravitative == gravitative def test_height_property(self, videogame_test, character_test): height = 100 character_test.height = height assert character_test.height == height def test_image_filename_property(self, character_filename_test): ch = Character(character_filename_test) assert ch.image_filename == character_filename_test def test_image_path_property(self, character_filename_test): ch = Character(character_filename_test) assert ch.image_path == join( paths.CHARACTERS_DIR, character_filename_test ) def test_jump_force_property(self, videogame_test, character_test): assert ( character_test.jump_force == settings.CHARACTER_DEFAULT_JUMP_FORCE ) def test_jumping_property(self, videogame_test, character_test): assert character_test.jumping == False def test_lives_property(self, videogame_test, character_test): lives = 3 character_test.lives = lives assert character_test.lives == lives def test_lives_no_property(self, videogame_test, secondary_character_test): assert secondary_character_test.lives is None def test_name_property(self, character_filename_test, character_name_test): ch = Character(character_filename_test, character_name_test) assert ch.name == character_name_test def test_position_property(self, videogame_test, character_test): x, y = 200, 300 character_test.x = x character_test.y = y assert character_test.position == (x, y) def test_scale_property(self, videogame_test, character_test): scale = 0.5 character_test.scale = scale assert character_test.scale == scale def test_score_property(self, videogame_test, character_test): score = 3 character_test.score = score assert character_test.score == score def test_score_no_property(self, videogame_test, secondary_character_test): assert secondary_character_test.score is None def test_speaking_property(self, videogame_test, character_test): character_test.speak('foo') assert character_test.speaking == True def test_speech_bubble_property(self, videogame_test, character_test): assert isinstance(character_test.speech_bubble, SpeechBubble) def test_speed_property(self, videogame_test, character_test): speed = 20 character_test.speed = speed assert character_test.speed == speed def test_touchable_property(self, videogame_test, character_test): touchable = True character_test.touchable = touchable assert character_test.touchable == touchable def test_visible_property(self, videogame_test, character_test): visible = False character_test.visible = visible assert character_test.visible == visible def test_width_property(self, videogame_test, character_test): width = 100 character_test.width = width assert character_test.width == width def test_calculate_relative_position_top( self, videogame_test, character_test, secondary_character_test ): character_test.move_to(0, 0) secondary_character_test.move_to(0, character_test.height + 1) assert ( character_test.calculate_relative_position( secondary_character_test ) == character_test.TOP ) def test_calculate_relative_position_bottom( self, videogame_test, character_test, secondary_character_test ): character_test.move_to(0, secondary_character_test.height + 1) secondary_character_test.move_to(0, 0) assert ( character_test.calculate_relative_position( secondary_character_test ) == character_test.BOTTOM ) def test_calculate_relative_position_left( self, videogame_test, character_test, secondary_character_test ): character_test.move_to(0, 0) secondary_character_test.move_to(character_test.width + 1, 0) assert ( character_test.calculate_relative_position( secondary_character_test ) == character_test.LEFT ) def test_calculate_relative_position_right( self, videogame_test, character_test, secondary_character_test ): character_test.move_to(secondary_character_test.width + 1, 0) secondary_character_test.move_to(0, 0) assert ( character_test.calculate_relative_position( secondary_character_test ) == character_test.RIGHT ) def test_move_with_wrong_coordinates(self, videogame_test, character_test): with pytest.raises(TypeError) as e: character_test.move('foo', 'bar') assert str(e.value) == 'amount to move must be an integer' def test_move_with_wrong_key_type(self, videogame_test, character_test): with pytest.raises(TypeError) as e: character_test.move(5, 3, key=-1) assert str(e.value) == 'key pressed must be a string' def test_rotate_with_wrong_type(self, videogame_test, character_test): with pytest.raises(TypeError) as e: character_test.rotate('foo') assert str(e.value) == 'the rotation increment must be an integer' def test_decrease_with_integer_argument( self, videogame_test, character_test ): character_test.decrease(2) def test_decrease_with_wrong_type(self, videogame_test, character_test): with pytest.raises(TypeError) as e: character_test.decrease('foo') assert str(e.value) == 'the decrement must be a float number' def test_increase_with_integer_argument( self, videogame_test, character_test ): character_test.increase(2) def test_increase_with_wrong_type(self, videogame_test, character_test): with pytest.raises(TypeError) as e: character_test.increase('foo') assert str(e.value) == 'the increment must be a float number' def test_scale_with_wrong_factor_type( self, videogame_test, character_test ): with pytest.raises(TypeError) as e: character_test.scale_to('foo') assert ( str(e.value) == 'the scale factor must be a positive number (float or int)' ) def test_scale_with_a_negative_factor( self, videogame_test, character_test ): with pytest.raises(ValueError) as e: character_test.scale_to(-1) assert ( str(e.value) == 'the scale factor must be a non-negative number (float or int)' ) def test_flip_with_wrong_type(self, videogame_test, character_test): with pytest.raises(TypeError) as e: character_test.flip('foo', 'bar') assert ( str(e.value) == 'both the horizontal and vertical axis must be booleans' ) def test_set_angle_with_wrong_type(self, videogame_test, character_test): with pytest.raises(TypeError) as e: character_test.set_angle('foo') assert str(e.value) == 'the rotation angle must be an integer' @pytest.mark.parametrize('height', [True, False, 'foo', [1, 2, 3]]) def test_set_height_with_wrong_type( self, videogame_test, character_test, height ): with pytest.raises(TypeError) as e: character_test.set_height(height) assert str(e.value) == 'height must be a non-negative integer' def test_set_height_with_a_negative_amount( self, videogame_test, character_test ): with pytest.raises(ValueError) as e: character_test.set_height(-1) assert str(e.value) == 'height must be a non-negative integer' def test_set_keys_with_wrong_type(self, videogame_test, character_test): with pytest.raises(TypeError) as e: character_test.set_keys('foo') assert ( str(e.value) == 'the predefined keys must be a dict. No keys are loaded' ) def test_set_position_with_wrong_types( self, videogame_test, character_test ): with pytest.raises(TypeError) as e: character_test.set_position('foo', 'bar') assert str(e.value) == 'the position must be a tuple or list (x, y)' def test_set_position_with_wrong_number_of_parameters( self, videogame_test, character_test ): with pytest.raises(ValueError) as e: character_test.set_position((2, 3, 4)) assert str(e.value) == 'the position has two coordinates (x, y)' @pytest.mark.parametrize('width', [True, False, 'foo', [1, 2, 3]]) def test_set_width_with_wrong_type( self, videogame_test, character_test, width ): with pytest.raises(TypeError) as e: character_test.set_width(width) assert str(e.value) == 'width must be a non-negative integer' def test_set_width_with_a_negative_amount( self, videogame_test, character_test ): with pytest.raises(ValueError) as e: character_test.set_width(-1) assert str(e.value) == 'width must be a non-negative integer' def test_touch_with_wrong_characters_type( self, videogame_test, character_test ): with pytest.raises(TypeError) as e: character_test.touch('foo') assert ( str(e.value) == 'the instances to be touched must be a character, a group or a list of characters' ) def test_touch_with_list_not_all_characters( self, videogame_test, character_test, secondary_character_test ): with pytest.raises(TypeError) as e: character_test.touch([secondary_character_test, 'foo']) assert ( str(e.value) == 'the instances to be touched must be a character, a group or a list of characters' ) def test_touch_with_wrong_key_type( self, videogame_test, character_test, secondary_character_test ): with pytest.raises(TypeError) as e: character_test.touch(secondary_character_test, key=-1) assert str(e.value) == 'key pressed must be a string' def test_touch_without_sprites_colliding( self, videogame_test, character_test, secondary_character_test ): character_test.move_to(0, 0) secondary_character_test.move_to(5000, 500) vg.update() assert character_test.touch(secondary_character_test) == [] # TODO: assert ?? def test_jump_with_force_as_integer(self, videogame_test, character_test): character_test.jump(5) def test_jump_with_wrong_force_type(self, videogame_test, character_test): with pytest.raises(TypeError) as e: character_test.jump('foo') assert ( str(e.value) == 'the jump force must be a non-negative float number' ) def test_jump_with_negative_force(self, videogame_test, character_test): with pytest.raises(ValueError) as e: character_test.jump(-5) assert str(e.value) == 'the jump force must be a non-negative float' def test_jump_with_wrong_key_type(self, videogame_test, character_test): with pytest.raises(TypeError) as e: character_test.jump(5, key=-1) assert str(e.value) == 'key pressed must be a string' def test_jump_counter_when_updating_jump( self, videogame_test, character_test ): character_test.jump() previous_jump_counter = character_test._jump_counter character_test._update_jump() assert character_test._jump_counter == previous_jump_counter - 1 def test_update_rect_position_with_wrong_traking_type( self, videogame_test, character_test ): with pytest.raises(TypeError) as e: character_test._update_rect_position(tracking='foo') assert str(e.value) == 'the tracking argument must be a boolean' """ def test_update_rect_position_when_character_moved( self, videogame_test, character_test ): character_test.move_to(1000, 0) character_test._update_rect_position(tracking=True) character_test.move_to(3000, 0) character_test._update_rect_position(tracking=True) """