Back to Repositories

Testing Composer Command Correction Logic in TheFuck

This test suite validates the Composer command correction functionality in TheFuck, focusing on handling invalid command inputs and suggesting correct alternatives. It verifies the pattern matching and command correction logic for common Composer command mistakes.

Test Coverage Overview

The test suite provides comprehensive coverage of Composer command validation scenarios.

Key areas tested include:
  • Invalid command detection (‘udpate’ vs ‘update’)
  • Multiple suggestion handling (selfupdate, self-update, update)
  • Package installation command correction
  • Non-Composer command validation

Implementation Analysis

The testing approach uses pytest fixtures to simulate various Composer command outputs and error scenarios. The implementation follows a pattern of validating both the match detection and command correction logic separately, ensuring accurate command suggestions for different error cases.

The tests utilize pytest’s fixture management for efficient test data organization and reuse.

Technical Details

Testing tools and configuration:
  • Pytest framework for test organization
  • Custom fixtures for error message simulation
  • Command object usage for input processing
  • InvalidArgumentException handling
  • String pattern matching for command correction

Best Practices Demonstrated

The test suite exemplifies several testing best practices:

  • Separation of concerns between matching and correction logic
  • Comprehensive edge case coverage
  • Clear test data organization using fixtures
  • Explicit negative test cases
  • Maintainable and readable test structure

nvbn/thefuck

tests/rules/test_composer_not_command.py

            
import pytest
from thefuck.rules.composer_not_command import match, get_new_command
from thefuck.types import Command


@pytest.fixture
def composer_not_command():
    # that weird spacing is part of the actual command output
    return (
        '
'
        '
'
        '                                    
'
        '  [InvalidArgumentException]        
'
        '  Command "udpate" is not defined.  
'
        '  Did you mean this?                
'
        '      update                        
'
        '                                    
'
        '
'
        '
'
    )


@pytest.fixture
def composer_not_command_one_of_this():
    # that weird spacing is part of the actual command output
    return (
        '
'
        '
'
        '                                   
'
        '  [InvalidArgumentException]       
'
        '  Command "pdate" is not defined.  
'
        '  Did you mean one of these?       
'
        '      selfupdate                   
'
        '      self-update                  
'
        '      update                       
'
        '                                   
'
        '
'
        '
'
    )


@pytest.fixture
def composer_require_instead_of_install():
    return 'Invalid argument package. Use "composer require package" instead to add packages to your composer.json.'


def test_match(composer_not_command, composer_not_command_one_of_this, composer_require_instead_of_install):
    assert match(Command('composer udpate',
                         composer_not_command))
    assert match(Command('composer pdate',
                         composer_not_command_one_of_this))
    assert match(Command('composer install package',
                         composer_require_instead_of_install))
    assert not match(Command('ls update', composer_not_command))


def test_get_new_command(composer_not_command, composer_not_command_one_of_this, composer_require_instead_of_install):
    assert (get_new_command(Command('composer udpate',
                                    composer_not_command))
            == 'composer update')
    assert (get_new_command(Command('composer pdate',
                                    composer_not_command_one_of_this))
            == 'composer selfupdate')
    assert (get_new_command(Command('composer install package',
                                    composer_require_instead_of_install))
            == 'composer require package')