Back to Repositories

Testing Mercurial Command Correction Logic in thefuck

This test suite validates the Mercurial command correction functionality in the thefuck project, focusing on handling ambiguous and incorrect Mercurial (hg) commands. It ensures the system can properly identify and suggest corrections for mistyped or ambiguous Mercurial commands.

Test Coverage Overview

The test suite provides comprehensive coverage of Mercurial command correction scenarios:

  • Tests for matching invalid commands and suggesting corrections
  • Validation of ambiguous command handling
  • Edge cases including repository not found scenarios
  • Multiple suggestion handling for similar commands

Implementation Analysis

The testing approach utilizes pytest’s parametrize feature to efficiently test multiple scenarios with minimal code duplication. Each test focuses on specific command correction aspects:

  • Command matching validation
  • Possibility extraction from error messages
  • New command generation based on suggestions

Technical Details

Testing implementation leverages:

  • pytest framework for test organization
  • Command class from thefuck.types
  • Parametrized test cases for varied scenarios
  • Custom assertion functions for validation

Best Practices Demonstrated

The test suite exemplifies several testing best practices:

  • Systematic test case organization using parametrize
  • Clear separation of test scenarios
  • Comprehensive edge case coverage
  • Consistent test structure and naming conventions

nvbn/thefuck

tests/rules/test_mercurial.py

            
import pytest

from thefuck.types import Command
from thefuck.rules.mercurial import (
    extract_possibilities, match, get_new_command
)


@pytest.mark.parametrize('command', [
    Command('hg base', (
        "hg: unknown command 'base'"
        '
(did you mean one of blame, phase, rebase?)'
    )),
    Command('hg branchch', (
        "hg: unknown command 'branchch'"
        '
(did you mean one of branch, branches?)'
    )),
    Command('hg vert', (
        "hg: unknown command 'vert'"
        '
(did you mean one of revert?)'
    )),
    Command('hg lgo -r tip', (
        "hg: command 're' is ambiguous:"
        '
(did you mean one of log?)'
    )),
    Command('hg rerere', (
        "hg: unknown command 'rerere'"
        '
(did you mean one of revert?)'
    )),
    Command('hg re', (
        "hg: command 're' is ambiguous:"
        '
    rebase recover remove rename resolve revert'
    )),
    Command('hg re re', (
        "hg: command 're' is ambiguous:"
        '
    rebase recover remove rename resolve revert'
    )),
])
def test_match(command):
    assert match(command)


@pytest.mark.parametrize('command', [
    Command('hg', (
        '
Mercurial Distributed SCM

basic commands:'
    )),
    Command('hg asdf', (
        "hg: unknown command 'asdf'"
        '
Mercurial Distributed SCM

basic commands:'
    )),
    Command('hg qwer', (
        "hg: unknown command 'qwer'"
        '
Mercurial Distributed SCM

basic commands:'
    )),
    Command('hg me', (
        "
abort: no repository found in './thefuck' (.hg not found)!"
    )),
    Command('hg reb', (
        "
abort: no repository found in './thefuck' (.hg not found)!"
    )),
    Command('hg co', (
        "
abort: no repository found in './thefuck' (.hg not found)!"
    )),
])
def test_not_match(command):
    assert not match(command)


@pytest.mark.parametrize('command, possibilities', [
    (Command('hg base', (
        "hg: unknown command 'base'"
        '
(did you mean one of blame, phase, rebase?)'
    )), ['blame', 'phase', 'rebase']),
    (Command('hg branchch', (
        "hg: unknown command 'branchch'"
        '
(did you mean one of branch, branches?)'
    )), ['branch', 'branches']),
    (Command('hg vert', (
        "hg: unknown command 'vert'"
        '
(did you mean one of revert?)'
    )), ['revert']),
    (Command('hg lgo -r tip', (
        "hg: command 're' is ambiguous:"
        '
(did you mean one of log?)'
    )), ['log']),
    (Command('hg rerere', (
        "hg: unknown command 'rerere'"
        '
(did you mean one of revert?)'
    )), ['revert']),
    (Command('hg re', (
        "hg: command 're' is ambiguous:"
        '
    rebase recover remove rename resolve revert'
    )), ['rebase', 'recover', 'remove', 'rename', 'resolve', 'revert']),
    (Command('hg re re', (
        "hg: command 're' is ambiguous:"
        '
    rebase recover remove rename resolve revert'
    )), ['rebase', 'recover', 'remove', 'rename', 'resolve', 'revert']),
])
def test_extract_possibilities(command, possibilities):
    assert extract_possibilities(command) == possibilities


@pytest.mark.parametrize('command, new_command', [
    (Command('hg base', (
        "hg: unknown command 'base'"
        '
(did you mean one of blame, phase, rebase?)'
    )), 'hg rebase'),
    (Command('hg branchch', (
        "hg: unknown command 'branchch'"
        '
(did you mean one of branch, branches?)'
    )), 'hg branch'),
    (Command('hg vert', (
        "hg: unknown command 'vert'"
        '
(did you mean one of revert?)'
    )), 'hg revert'),
    (Command('hg lgo -r tip', (
        "hg: command 're' is ambiguous:"
        '
(did you mean one of log?)'
    )), 'hg log -r tip'),
    (Command('hg rerere', (
        "hg: unknown command 'rerere'"
        '
(did you mean one of revert?)'
    )), 'hg revert'),
    (Command('hg re', (
        "hg: command 're' is ambiguous:"
        '
    rebase recover remove rename resolve revert'
    )), 'hg rebase'),
    (Command('hg re re', (
        "hg: command 're' is ambiguous:"
        '
    rebase recover remove rename resolve revert'
    )), 'hg rebase re'),
])
def test_get_new_command(command, new_command):
    assert get_new_command(command) == new_command