1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
from __future__ import annotations
import os
import sys
from typing import TYPE_CHECKING
import pytest
from app_model import Application
from app_model.expressions import Context
from app_model.types import Action
from app_model.types._menu_rule import MenuRule
if TYPE_CHECKING:
from conftest import FullApp
def test_app_create() -> None:
assert Application.get_app("my_app") is None
app = Application("my_app")
assert Application.get_app("my_app") is app
# NOTE: for some strange reason, this test fails if I move this line
# below the error assertion below... I don't know why.
assert Application.get_or_create("my_app") is app
with pytest.raises(ValueError, match="Application 'my_app' already exists"):
Application("my_app")
assert repr(app) == "Application('my_app')"
Application.destroy("my_app")
def test_app(full_app: FullApp) -> None:
app = full_app
app.commands.execute_command(app.Commands.OPEN)
app.mocks.open.assert_called_once()
app.commands.execute_command(app.Commands.COPY)
app.mocks.copy.assert_called_once()
app.commands.execute_command(app.Commands.PASTE)
app.mocks.paste.assert_called_once()
def test_sorting(full_app: FullApp) -> None:
groups = list(full_app.menus.iter_menu_groups(full_app.Menus.EDIT))
assert len(groups) == 3
[_g0, g1, g2] = groups
assert all(i.group == "1_undo_redo" for i in g1)
assert all(i.group == "2_copy_paste" for i in g2)
assert [i.command.title for i in g1] == ["Undo", "Redo"]
assert [i.command.title for i in g2] == ["Copy", "Paste"]
def test_action_import_by_string(full_app: FullApp) -> None:
"""the REDO command is declared as a string in the conftest.py file
This tests that it can be lazily imported at callback runtime and executed
"""
assert "fake_module" not in sys.modules
assert full_app.commands.execute_command(full_app.Commands.REDO).result()
assert "fake_module" in sys.modules
full_app.mocks.redo.assert_called_once()
# tests what happens when the module cannot be found
with pytest.raises(
ModuleNotFoundError, match="Command 'unimportable' was not importable"
):
full_app.commands.execute_command(full_app.Commands.UNIMPORTABLE)
# the second time we try within a session, nothing should happen
full_app.commands.execute_command(full_app.Commands.UNIMPORTABLE)
# tests what happens when the object is not callable cannot be found
with pytest.raises(
TypeError,
match=r"Command 'not\.callable' did not resolve to a callble object",
):
full_app.commands.execute_command(full_app.Commands.NOT_CALLABLE)
# the second time we try within a session, nothing should happen
full_app.commands.execute_command(full_app.Commands.NOT_CALLABLE)
def test_action_raises_exception(full_app: FullApp) -> None:
result = full_app.commands.execute_command(full_app.Commands.RAISES)
with pytest.raises(ValueError):
result.result()
# the function that raised the exception is `_raise_an_error` in conftest.py
assert str(result.exception()) == "This is an error"
assert not full_app.raise_synchronous_exceptions
full_app.raise_synchronous_exceptions = True
assert full_app.raise_synchronous_exceptions
with pytest.raises(ValueError):
full_app.commands.execute_command(full_app.Commands.RAISES)
def test_app_context() -> None:
app = Application("app1")
assert isinstance(app.context, Context)
Application.destroy("app1")
assert app.context["is_windows"] == (os.name == "nt")
assert "is_mac" in app.context
assert "is_linux" in app.context
app = Application("app2", context={"a": 1})
assert isinstance(app.context, Context)
assert app.context["a"] == 1
Application.destroy("app2")
app = Application("app3", context=Context({"a": 1}))
assert isinstance(app.context, Context)
assert app.context["a"] == 1
Application.destroy("app3")
with pytest.raises(TypeError, match="context must be a Context or MutableMapping"):
Application("app4", context=1) # type: ignore[arg-type]
def test_register_actions() -> None:
app = Application("app5")
actions = app.registered_actions
assert not actions
dispose = app.register_action(
"my_action", title="My Action", callback=lambda: None, menus=["Window"]
)
assert "my_action" in actions
assert isinstance(action := actions["my_action"], Action)
assert action.menus == [MenuRule(id="Window")]
dispose()
assert "my_action" not in actions
assert not actions
|