diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml index 5b81368ee8..c2774860d7 100644 --- a/.github/workflows/ci-workflow.yml +++ b/.github/workflows/ci-workflow.yml @@ -13,10 +13,10 @@ jobs: housekeeping: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Set up Python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 with: python-version: 3.13.5 @@ -54,9 +54,9 @@ jobs: matrix: python-version: [3.10.6, 3.11.2, 3.12, 3.13.5] steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/issue-commenter.yml b/.github/workflows/issue-commenter.yml index 615d5e74bf..f4ef326363 100644 --- a/.github/workflows/issue-commenter.yml +++ b/.github/workflows/issue-commenter.yml @@ -9,7 +9,7 @@ jobs: name: Comments for every NEW issue. steps: - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Read issue-comment.md id: issue-comment diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 29b936390e..e729b81eec 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -8,7 +8,7 @@ jobs: stale: runs-on: ubuntu-24.04 steps: - - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 + - uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 with: repo-token: ${{ secrets.GITHUB_TOKEN }} days-before-stale: 21 diff --git a/.github/workflows/test-runner.yml b/.github/workflows/test-runner.yml index b5bac60e8b..44fb4ba968 100644 --- a/.github/workflows/test-runner.yml +++ b/.github/workflows/test-runner.yml @@ -10,6 +10,6 @@ jobs: test-runner: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Run test-runner run: docker compose run test-runner diff --git a/exercises/concept/ellens-alien-game/classes_test.py b/exercises/concept/ellens-alien-game/classes_test.py index a73e652cfa..b7afb7cc3e 100644 --- a/exercises/concept/ellens-alien-game/classes_test.py +++ b/exercises/concept/ellens-alien-game/classes_test.py @@ -7,16 +7,16 @@ except ImportError as import_fail: # pylint: disable=raise-missing-from raise ImportError("\n\nMISSING CLASS --> We tried to import the 'Alien' class from " - "your classes.py file, but could not find it." - "Did you misname or forget to create it?") from None + 'your classes.py file, but could not find it. ' + 'Did you misname or forget to create it?') from None try: from classes import new_aliens_collection except ImportError as err: - raise ImportError("\n\nMISSING FUNCTION --> We tried to import the " - "new_aliens_collection() function " - "from your classes.py file, but could not find it. " - "Did you misname or forget to create it?") from None + raise ImportError('\n\nMISSING FUNCTION --> We tried to import the ' + 'new_aliens_collection() function ' + 'from your classes.py file, but could not find it. ' + 'Did you misname or forget to create it?') from None class ClassesTest(unittest.TestCase): @@ -38,7 +38,7 @@ def test_alien_has_health(self): alien = Alien(0, 0) error_message = (f'Created a new Alien by calling Alien(0, 0). ' f'The new Alien has a health of {alien.health}, ' - f'but the tests expect health = 3') + f'but the tests expect health = 3.') self.assertEqual(3, alien.health, msg=error_message) @@ -72,7 +72,6 @@ def test_alien_hit_method(self): There are two valid interpretations for this method/task. `self.health -= 1` and `self.health = max(0, self.health - 1)` The tests for this task reflect this ambiguity. - """ test_data = [1, 2, 3, 4, 5, 6] @@ -99,6 +98,7 @@ def test_alien_hit_method(self): @pytest.mark.task(taskno=3) def test_alien_is_alive_method(self): + """Test the is_alive() method returns the expected values after a number of hits.""" alien = Alien(0, 1) alive_error = ('Created a new Alien and called hit(). ' @@ -106,8 +106,8 @@ def test_alien_is_alive_method(self): 'while alien.health is greater than 0.') dead_error = ('Created a new Alien and called hit(). ' - 'The function is_alive() is returning True (alive) ' - 'while alien.health is less than or equal to 0.') + 'The function is_alive() is returning True (alive) ' + 'while alien.health is less than or equal to 0.') for _ in range(5): alien.hit() @@ -118,6 +118,7 @@ def test_alien_is_alive_method(self): @pytest.mark.task(taskno=4) def test_alien_teleport_method(self): + """Test the teleport method updates the alien's coordinates.""" alien = Alien(0, 0) alien.teleport(-1, -4) @@ -130,11 +131,12 @@ def test_alien_teleport_method(self): @pytest.mark.task(taskno=5) def test_alien_collision_detection_method(self): + """Test the collision_detection() method can be called and returns None.""" alien = Alien(7, 3) error_message = ('Created a new Alien at (7,3) and called ' 'alien.collision_detection(Alien(7, 2)). ' f'The method returned {alien.collision_detection(Alien(7, 2))}, ' - 'but the tests expected None. ') + 'but the tests expected None.') self.assertIsNone(alien.collision_detection(Alien(7, 2)), msg=error_message) @@ -144,26 +146,35 @@ def test_alien_class_variable(self): """Test class attribute/variables are identical across instances.""" alien_one, alien_two = Alien(0, 2), Alien(-6, -1) - Alien.health = 6 created_error_message = ('Created two new Aliens and requested the ' 'total_aliens_created attribute for each one. ' f'Received {alien_one.total_aliens_created, alien_two.total_aliens_created} ' f'for total_aliens_created, but the tests expect ' - f'the class attributes for each newly created Alien to be identical. ') - - health_error_message = ('Created two new Aliens and requested the ' - f'health attribute for each one. Received {alien_one.health, alien_two.health} ' - 'for health, but the tests expect the class ' - 'attributes for each newly created Alien to be identical. ') + f'the class attributes for each newly created Alien to be identical.') self.assertEqual(alien_two.total_aliens_created, alien_one.total_aliens_created, msg=created_error_message) - self.assertEqual(alien_two.health, - alien_one.health, - msg=health_error_message) + @pytest.mark.task(taskno=6) + def test_alien_health_is_instance_variable(self): + """Test the health is an instance variable and not a class variable.""" + + alien_one, alien_two = Alien(0, 2), Alien(-6, -1) + alien_one.hit() + + error_message = ('Created two new Aliens and called hit() on one of them. ' + f'Received {alien_one.health, alien_two.health} for health, ' + 'but the tests expect them to have different health as ' + 'only one was hit. Are you using a class variable for the health?') + + # This checks that a class attribute, Alien.health, is not being used. + # If a class attribute is being used, hit() would update the health across + # all instances of the class. + self.assertNotEqual(alien_two.health, + alien_one.health, + msg=error_message) @pytest.mark.task(taskno=6) def test_alien_total_aliens_created(self): @@ -182,9 +193,9 @@ def test_alien_total_aliens_created(self): aliens.append(Alien(-5, -5)) def error_text(alien, variable): - return ('Created two additional Aliens for the session.' + return ('Created two additional Aliens for the session. ' f"Alien number {alien}'s total_aliens_created variable " - f"is equal to {variable}, but the tests expected all " + f'is equal to {variable}, but the tests expected all ' 'total_aliens_created variables for all instances to be ' 'equal to number of alien instances created (i.e. 3).')