meta_package_manager.tests package#

Submodules#

meta_package_manager.tests.conftest module#

meta_package_manager.tests.conftest.pytest_addoption(parser)[source]#

Add custom command line options.

Based on Pytest’s documentation examples.

By default, runs non-destructive tests and skips destructive ones.

meta_package_manager.tests.conftest.pytest_configure(config)[source]#

Register custom markers.

meta_package_manager.tests.conftest.solve_destructive_options(config)[source]#

Solve the destructive options to determine which tests to run.

Return type:

tuple[bool, bool]

meta_package_manager.tests.conftest.pytest_collection_modifyitems(config, items)[source]#

Either skip or run destructive tests based on command line options.

meta_package_manager.tests.conftest.pytest_report_header(config, start_path)[source]#

Display destructive options status in test report header.

Return type:

tuple[str, ...]

meta_package_manager.tests.conftest.invoke(extra_runner)[source]#
meta_package_manager.tests.conftest.subcmd()[source]#

Fixture used in test_cli_*.py files to set the subcommand arguments in all CLI calls.

Must returns a string or an iterable of strings. Defaults to None, which allows tests relying on this fixture to selectively skip running.

meta_package_manager.tests.conftest.PACKAGE_IDS = {'apm': 'markdown-pdf', 'apt': 'wget', 'apt-mint': 'exiftool', 'brew': 'meta-package-manager', 'cargo': 'colorous', 'cask': 'pngyu', 'choco': 'ccleaner', 'composer': 'illuminate/contracts', 'dnf': 'usd', 'emerge': 'dev-vcs/git', 'flatpak': 'org.gnome.Dictionary', 'gem': 'markdown', 'mas': '747648890', 'npm': 'raven', 'opkg': 'enigma2-hotplug', 'pacaur': 'manjaro-hello', 'pacman': 'manjaro-hello', 'paru': 'meta-package-manager', 'pip': 'meta-package-manager', 'pipx': 'meta-package-manager', 'pkg': 'dmg2img', 'scoop': '7zip', 'snap': 'standard-notes', 'steamcmd': '740', 'vscode': 'tamasfe.even-better-toml', 'yarn': 'awesome-lint', 'yay': 'meta-package-manager', 'yum': 'usd', 'zypper': 'git'}#

List of existing package IDs to install for each supported package manager.

Only to be used for destructive tests.

meta_package_manager.tests.conftest.pytest_runtest_teardown(item, nextitem)[source]#

Force the reset, after each subcommand test, of NPM’s cached CLI path.

This hack is applied on macOS only, in which parallel tests are messing up with the location of the system’s NPM binary. This ends up in cryptic test suite failures, as the npm CLI is moved around during execution:

Clearing the cli_path cached property forces mpm to re-search the npm binary on the system.

meta_package_manager.tests.test_bar_plugin module#

class meta_package_manager.tests.test_bar_plugin.TestBarPlugin[source]#

Bases: object

common_checklist = [('(🎁↑\\d+|📦✓)( ⚠️\\d+)? \\| dropdown=false$', True), ('-{3,5}$', True), ('(--)?🆙 Upgrade all \\S+ packages? \\| shell=\\S+( param\\d+=\\S+)+ refresh=true terminal=(false|true alternate=true)$', True), ('(--)?.+ \\| font=Menlo size=12 color=red trim=false ansi=false emojize=false( symbolize=false)?$', False)]#
plugin_output_checks(checklist, extra_env=None)[source]#

Run the plugin script and check its output against the checklist.

test_rendering(submenu_layout, table_rendering)[source]#
test_plugin_shell_invocation(shell_args)[source]#

Test execution of plugin on different shells.

Do not execute the complete search for outdated packages, just stop at searching for the mpm executable and extract its version.

test_python_shell_invocation(shell_args, python_args)[source]#

Test any Python shell invocation is properly configured and all are compatible with plugin requirements.

pytestmark = [Mark(name='skipif', args=(True,), kwargs={'reason': 'macOS required'})]#

meta_package_manager.tests.test_cli module#

class meta_package_manager.tests.test_cli.InspectCLIOutput[source]#

Bases: object

static evaluate_signals(mid, stdout, stderr)[source]#

Search in the CLI output for evidence that a manager has been retained.

..tip:

In the implementation, signals should be roughly sorted from most specific
to more forgiving.
Return type:

Iterator[bool]

check_manager_selection(result, selected=('apt', 'apt-mint', 'brew', 'cargo', 'composer', 'dnf', 'emerge', 'flatpak', 'gem', 'npm', 'opkg', 'pacaur', 'pacman', 'paru', 'pip', 'pipx', 'pkg', 'snap', 'steamcmd', 'vscode', 'yarn', 'yay', 'yum', 'zypper'), reference_set=('apt', 'apt-mint', 'brew', 'cargo', 'composer', 'dnf', 'emerge', 'flatpak', 'gem', 'npm', 'opkg', 'pacaur', 'pacman', 'paru', 'pip', 'pipx', 'pkg', 'snap', 'steamcmd', 'vscode', 'yarn', 'yay', 'yum', 'zypper'), strict_selection_match=True)[source]#

Check that user-selected managers are found in CLI’s output.

To establish that mpm CLI is properly selecting managers, we search for signals in CLI logs, by matching regular expressions against <stdout> and <stderr>. This strategy close the gap of testing internal code testing and end user experience.

Signals are expected to be implemented for each subcommand by the evaluate_signals() method.

strict_selection_match check that all selected managers are properly reported in CLI output and none are missing.

Caution

At this stage of the CLI execution, the order in which the managers are reported doesn’t matter because:

This explain the use of set() everywhere in this method.

class meta_package_manager.tests.test_cli.TestCommonCLI[source]#

Bases: object

Single tests for CLI behavior shared by all subcommands.

If we have to, we only run the test on a single, non-destructive subcommand (like mpm installed or mpm managers). Not all subcommands are tested.

That way we prevent running similar tests which are operating on the same, shared code path. Thus improving overall execution of the test suite.

test_executable_module()[source]#

Try running the CLI as a Python module.

Use the current Python executable so we don’t have to worry about missing dependencies.

test_timeout(invoke)[source]#

Check that the CLI exits with an error when a timeout is reached.

test_stats(invoke, stats_arg, active_stats)[source]#

Test the result on all combinations of optional statistics options.

class meta_package_manager.tests.test_cli.TestManagerSelection[source]#

Bases: InspectCLIOutput

Test selection of package managers to use.

Tests are performed here on the mpm managers subcommand, as it is a safe read-only operation that is supposed to work on all platforms, whatever the environment.

There is not need to test all subcommands, as the selection logic and code path is shared by all of them. See the implementation in meta_package_manager.pool.ManagerPool.select_managers().

static evaluate_signals(mid, stdout, stderr)[source]#

Borrow the signals from the --managers test suite.

Module is imported inplace to avoid circular import.

Return type:

Iterator[bool]

test_invalid_manager_selector(invoke, selector)[source]#
test_default_all_managers(invoke)[source]#

Test all available managers are selected by default.

test_manager_shortcuts(invoke, manager_id)[source]#

Test each manager selection shortcut.

test_manager_selection(invoke, args, expected)[source]#
test_conf_file_overrides_defaults(invoke, create_config)[source]#
test_conf_file_cli_override(invoke, create_config)[source]#
class meta_package_manager.tests.test_cli.CLISubCommandTests[source]#

Bases: InspectCLIOutput

All these tests runs on each subcommand.

This class doesn’t starts with Test as it is meant to be used as a template, inherited by sub-command specific test cases.

class meta_package_manager.tests.test_cli.CLITableTests[source]#

Bases: object

Test subcommands whose output is a configurable table.

Any table output is also allowed to be rendered as JSON.

test_all_table_rendering(invoke, mode)[source]#
test_json_output(invoke, subcmd)[source]#

JSON output is expected to be parseable if read from <stdout>.

Debug level messages are redirected to <stderr> and are not supposed to interfere with this behavior.

meta_package_manager.tests.test_cli_backup module#

meta_package_manager.tests.test_cli_backup.subcmd()[source]#
class meta_package_manager.tests.test_cli_backup.TestBackup[source]#

Bases: CLISubCommandTests

static evaluate_signals(mid, stdout, stderr)[source]#

Search in the CLI output for evidence that a manager has been retained.

..tip:

In the implementation, signals should be roughly sorted from most specific
to more forgiving.
test_default_all_managers_output_to_console(invoke, subcmd)[source]#
test_output_to_console(invoke, subcmd)[source]#
test_output_to_file(invoke, subcmd)[source]#
test_single_manager_file_output(manager_id, invoke, subcmd)[source]#

meta_package_manager.tests.test_cli_cleanup module#

meta_package_manager.tests.test_cli_cleanup.subcmd()[source]#
class meta_package_manager.tests.test_cli_cleanup.TestCleanup[source]#

Bases: CLISubCommandTests

static evaluate_signals(mid, stdout, stderr)[source]#

Search in the CLI output for evidence that a manager has been retained.

..tip:

In the implementation, signals should be roughly sorted from most specific
to more forgiving.

meta_package_manager.tests.test_cli_install_remove module#

meta_package_manager.tests.test_cli_install_remove.subcmd()[source]#
class meta_package_manager.tests.test_cli_install_remove.TestInstallRemove[source]#

Bases: CLISubCommandTests

Install and remove operations are siblings and sensible, so we regroup them under the same test suite.

Tip

Where we can, we invoke the install subcommand to install mpm with itself, so we can test externally contributed packaging.

static evaluate_signals(mid, stdout, stderr)[source]#

Search in the CLI output for evidence that a manager has been retained.

..tip:

In the implementation, signals should be roughly sorted from most specific
to more forgiving.
test_no_package_id(invoke, operation)[source]#
test_single_manager_install_and_remove(invoke, manager_id, package_id)[source]#

Test the installation and removal of a package with each manager.

meta_package_manager.tests.test_cli_installed module#

meta_package_manager.tests.test_cli_installed.subcmd()[source]#
class meta_package_manager.tests.test_cli_installed.TestInstalled[source]#

Bases: CLISubCommandTests, CLITableTests

static evaluate_signals(mid, stdout, stderr)[source]#

Search in the CLI output for evidence that a manager has been retained.

..tip:

In the implementation, signals should be roughly sorted from most specific
to more forgiving.
test_json_parsing(invoke, subcmd)[source]#

meta_package_manager.tests.test_cli_managers module#

meta_package_manager.tests.test_cli_managers.subcmd()[source]#
class meta_package_manager.tests.test_cli_managers.TestManagers[source]#

Bases: CLISubCommandTests, CLITableTests

static evaluate_signals(mid, stdout, stderr)[source]#

Search in the CLI output for evidence that a manager has been retained.

..tip:

In the implementation, signals should be roughly sorted from most specific
to more forgiving.
test_all_managers(invoke, subcmd, manager_id)[source]#

Check only the selected manager is listed.

test_unsupported_managers(invoke, subcmd, manager_id)[source]#
test_json_parsing(invoke, subcmd)[source]#

meta_package_manager.tests.test_cli_outdated module#

meta_package_manager.tests.test_cli_outdated.subcmd()[source]#
class meta_package_manager.tests.test_cli_outdated.TestOutdated[source]#

Bases: CLISubCommandTests, CLITableTests

static evaluate_signals(mid, stdout, stderr)[source]#

Search in the CLI output for evidence that a manager has been retained.

..tip:

In the implementation, signals should be roughly sorted from most specific
to more forgiving.
test_json_parsing(invoke, subcmd)[source]#

meta_package_manager.tests.test_cli_restore module#

meta_package_manager.tests.test_cli_restore.subcmd(create_config)[source]#

Seed common subcommand tests with a dummy file and content to allow the CLI to not fail on required file input.

class meta_package_manager.tests.test_cli_restore.TestRestore[source]#

Bases: CLISubCommandTests

static evaluate_signals(mid, stdout, stderr)[source]#

Search in the CLI output for evidence that a manager has been retained.

..tip:

In the implementation, signals should be roughly sorted from most specific
to more forgiving.
test_default_all_managers(invoke, create_config)[source]#
test_single_manager(invoke, create_config, manager_id)[source]#
test_ignore_unrecognized_manager(invoke, create_config)[source]#
test_restore_single_manager(invoke, create_config)[source]#
test_restore_excluded_manager(invoke, create_config)[source]#
test_empty_manager(invoke, create_config)[source]#
pytestmark = [Mark(name='skip', args=(), kwargs={'reason': 'Generated config file is not isolated from other tests.'})]#

meta_package_manager.tests.test_cli_sync module#

meta_package_manager.tests.test_cli_sync.subcmd()[source]#
class meta_package_manager.tests.test_cli_sync.TestSync[source]#

Bases: CLISubCommandTests

static evaluate_signals(mid, stdout, stderr)[source]#

Search in the CLI output for evidence that a manager has been retained.

..tip:

In the implementation, signals should be roughly sorted from most specific
to more forgiving.

meta_package_manager.tests.test_cli_upgrade module#

meta_package_manager.tests.test_cli_upgrade.subcmd()[source]#
class meta_package_manager.tests.test_cli_upgrade.TestUpgrade[source]#

Bases: CLISubCommandTests

Test the system-wide upgrade sub-command.

Danger

All tests here should me marked as destructive unless –dry-run parameter is passed.

static evaluate_signals(mid, stdout, stderr)[source]#

Search in the CLI output for evidence that a manager has been retained.

..tip:

In the implementation, signals should be roughly sorted from most specific
to more forgiving.
test_all_managers_dry_run_upgrade_all(invoke, all_option)[source]#
test_all_managers_upgrade_all(invoke, all_option)[source]#
test_single_manager_dry_run_upgrade_all(invoke, manager_id, all_option)[source]#
test_single_manager_upgrade_all(invoke, manager_id, all_option)[source]#

meta_package_manager.tests.test_cli_which module#

meta_package_manager.tests.test_cli_which.subcmd()[source]#
class meta_package_manager.tests.test_cli_which.TestWhich[source]#

Bases: CLISubCommandTests, CLITableTests

static evaluate_signals(mid, stdout, stderr)[source]#

Search in the CLI output for evidence that a manager has been retained.

..tip:

In the implementation, signals should be roughly sorted from most specific
to more forgiving.

meta_package_manager.tests.test_docs module#

meta_package_manager.tests.test_docs.test_project_metadata()[source]#
meta_package_manager.tests.test_docs.test_changelog()[source]#
meta_package_manager.tests.test_docs.test_new_package_manager_issue_template()[source]#

Check all platforms groups are referenced in the issue template.

meta_package_manager.tests.test_docs.test_labeller_rules()[source]#

meta_package_manager.tests.test_manager_apt module#

APT-specific tests.

class meta_package_manager.tests.test_manager_apt.TestAPT[source]#

Bases: object

test_nonempty_exact_search_results(invoke, exact_search)[source]#
pytestmark = [Mark(name='skipif', args=(False,), kwargs={'reason': 'Linux required'})]#

meta_package_manager.tests.test_manager_homebrew module#

Homebrew-specific tests.

meta_package_manager.tests.test_manager_homebrew.install_cask()[source]#

A fixture to install a Cask from a specific commit.

class meta_package_manager.tests.test_manager_homebrew.TestCask[source]#

Bases: object

test_autoupdate_unicode_name(invoke, install_cask)[source]#

See #16.

test_multiple_names(invoke, install_cask)[source]#

See #26.

pytestmark = [Mark(name='skip', args=(), kwargs={'reason': 'Cask repository structure changed too much to go back in time.'}), Mark(name='skipif', args=(True,), kwargs={'reason': 'macOS required'}), Mark(name='destructive', args=(), kwargs={})]#

meta_package_manager.tests.test_managers module#

meta_package_manager.tests.test_managers.test_xkcd_set()[source]#
meta_package_manager.tests.test_managers.test_deprecated(manager)[source]#
meta_package_manager.tests.test_managers.test_ascii_id(manager)[source]#

All package manager IDs should be short ASCII strings.

meta_package_manager.tests.test_managers.test_name(manager)[source]#

Check all managers have a name.

meta_package_manager.tests.test_managers.test_unique_names()[source]#
meta_package_manager.tests.test_managers.test_homepage_url(manager)[source]#
meta_package_manager.tests.test_managers.test_platforms(manager)[source]#

Check platforms is normalized as a frozenset.

meta_package_manager.tests.test_managers.test_requirement(manager)[source]#

Each manager is required to specify a minimal version or None.

meta_package_manager.tests.test_managers.test_cli_names_type(manager)[source]#

Check the pointed CLI name and path are file-system compatible.

meta_package_manager.tests.test_managers.test_cli_search_path(manager)[source]#
meta_package_manager.tests.test_managers.test_extra_env_type(manager)[source]#

Check that definitions environment variables as a dict of strings.

meta_package_manager.tests.test_managers.test_global_args_type(manager)[source]#

Check that definitions returns CLI args as a list of non-empty strings.

meta_package_manager.tests.test_managers.test_version_cli_options(manager)[source]#

Version CLI options must be a list of non empty strings.

meta_package_manager.tests.test_managers.test_version_regex(manager)[source]#

Version regex is required.

Check it compiles and match has a version group.

meta_package_manager.tests.test_managers.test_cli_path(manager)[source]#
meta_package_manager.tests.test_managers.test_query_parts(query, query_parts)[source]#
meta_package_manager.tests.test_managers.collect_props_ref()[source]#

Build the canonical reference from the base class.

We need to parse the AST so we can collect both attributes and naked type annotations.

meta_package_manager.tests.test_managers.test_operation_order()[source]#

Double check operation IDs are ordered and aligned to the base manager class and CLI implementation.

meta_package_manager.tests.test_managers.test_content_order(manager_class)[source]#

Lint each package manager definition file to check its code structure is the same as the canonical PackageManager base class.

meta_package_manager.tests.test_platforms module#

meta_package_manager.tests.test_platforms.test_unique_ids()[source]#

IDs must be unique.

meta_package_manager.tests.test_platforms.test_groups_content()[source]#
meta_package_manager.tests.test_platforms.test_platform_groups_no_overlap()[source]#

Check our platform groups are mutually exclusive.

meta_package_manager.tests.test_platforms.test_all_platforms_covered_by_groups(manager)[source]#

Check all platforms supported by managers are covered by a local group.

meta_package_manager.tests.test_pool module#

meta_package_manager.tests.test_pool.test_manager_definition_inventory()[source]#

Check all classes implementing a package manager are accounted for in the pool.

meta_package_manager.tests.test_pool.test_manager_classes_order()[source]#

Check manager classes are ordered by their IDs.

meta_package_manager.tests.test_pool.test_manager_count()[source]#

Check all implemented package managers are accounted for, and unique.

meta_package_manager.tests.test_pool.test_cached_pool()[source]#
meta_package_manager.tests.test_pool.test_maintained_managers(manager_id)[source]#
meta_package_manager.tests.test_pool.test_supported_managers(manager_id)[source]#
meta_package_manager.tests.test_pool.test_unsupported_managers(manager_id)[source]#
meta_package_manager.tests.test_pool.test_manager_groups()[source]#

Test relationships between manager groups.

meta_package_manager.tests.test_pool.test_extra_option_allowlist()[source]#
meta_package_manager.tests.test_pool.test_select_managers(kwargs, expected)[source]#

We use tuple everywhere so we can check that select_managers() conserve the original order.

meta_package_manager.tests.test_specifier module#

meta_package_manager.tests.test_specifier.test_purl_map()[source]#
meta_package_manager.tests.test_specifier.props(spec)[source]#

Utility to help compares specifiers between themselves.

I.e. all properties of specifiers are the same but the raw_specs property.

meta_package_manager.tests.test_specifier.test_parse_specs(spec_string, expected)[source]#
meta_package_manager.tests.test_specifier.test_reduce_specs(spec_strings, target_managers, expected)[source]#

meta_package_manager.tests.test_version module#

meta_package_manager.tests.test_version.reverse_fixtures(table)[source]#

Utility method to reverse a tuple of tuples.

meta_package_manager.tests.test_version.test_token_allowed_instantiation(value)[source]#
meta_package_manager.tests.test_version.test_token_unauthorized_instantiation(value)[source]#
meta_package_manager.tests.test_version.test_token_eq(token, value)[source]#
meta_package_manager.tests.test_version.test_token_ne(token, value)[source]#
meta_package_manager.tests.test_version.test_token_gt(token, value)[source]#
meta_package_manager.tests.test_version.test_token_lt(token, value)[source]#
meta_package_manager.tests.test_version.test_token_ge(token, value)[source]#
meta_package_manager.tests.test_version.test_token_le(token, value)[source]#
meta_package_manager.tests.test_version.test_token_hash()[source]#
meta_package_manager.tests.test_version.test_tokenized_string_allowed_instantiation(value)[source]#
meta_package_manager.tests.test_version.test_tokenized_string_unauthorized_instantiation(value)[source]#
meta_package_manager.tests.test_version.test_tokenized_string_hash()[source]#
meta_package_manager.tests.test_version.test_tokenized_string_noop_instantiation()[source]#
meta_package_manager.tests.test_version.test_tokenized_string_idempotent_instantiation()[source]#
meta_package_manager.tests.test_version.test_tokenized_string_deepcopy()[source]#
meta_package_manager.tests.test_version.test_version_tokenizer(v_string, v_tuple)[source]#
meta_package_manager.tests.test_version.test_version_comparison_gt(ver1, ver2)[source]#
meta_package_manager.tests.test_version.test_version_comparison_lt(ver1, ver2)[source]#
meta_package_manager.tests.test_version.test_version_sorting(sequence)[source]#