From 6f082889c4d364f3fe256524c9af556015ad96a6 Mon Sep 17 00:00:00 2001 From: Christoph Ladurner Date: Sat, 9 Dec 2023 22:05:51 +0100 Subject: [PATCH] break: remove decorator --- flask_menu/__init__.py | 3 +- flask_menu/decorators.py | 95 ---------------------- tests/test_core.py | 168 +++++++++++---------------------------- 3 files changed, 49 insertions(+), 217 deletions(-) delete mode 100644 flask_menu/decorators.py diff --git a/flask_menu/__init__.py b/flask_menu/__init__.py index 4bb543e..02bfc7a 100644 --- a/flask_menu/__init__.py +++ b/flask_menu/__init__.py @@ -14,11 +14,10 @@ Those menus can be then displayed using templates. """ -from .decorators import register_menu from .ext import Menu from .menu import MenuNode from .proxies import current_menu __version__ = "1.0.1" -__all__ = ("current_menu", "Menu", "MenuNode", "__version__", "register_menu") +__all__ = ("current_menu", "Menu", "MenuNode", "__version__") diff --git a/flask_menu/decorators.py b/flask_menu/decorators.py deleted file mode 100644 index 5bcf5fc..0000000 --- a/flask_menu/decorators.py +++ /dev/null @@ -1,95 +0,0 @@ -# -*- coding: utf-8 -*- -# This file is part of Flask-Menu -# Copyright (C) 2013, 2014, 2015, 2017 CERN -# Copyright (C) 2017 Marlin Forbes -# Copyright (C) 2023 Graz University of Technology. -# -# Flask-Menu is free software; you can redistribute it and/or modify -# it under the terms of the Revised BSD License; see LICENSE file for -# more details. - -"""Register menu.""" - -from inspect import getfullargspec - -from flask import Blueprint - -from .proxies import current_menu - - -def register_menu( - app, - path, - text, - order=0, - endpoint_arguments_constructor=None, - dynamic_list_constructor=None, - active_when=None, - visible_when=None, - **kwargs, -): - """Decorate endpoints that should be displayed in a menu. - - Example:: - - @register_menu(app, '.', _('Home')) - def index(): - pass - - :param app: Application or Blueprint which owns the - function view. - :param path: Path to this item in menu hierarchy, - for example 'main.category.item'. Path can be an object - with custom __str__ method: it will be converted on first request, - therefore you can use current_app inside this __str__ method. - :param text: Text displayed as link. - :param order: Index of item among other items in the same menu. - :param endpoint_arguments_constructor: Function returning dict of - arguments passed to url_for when creating the link. - :param active_when: Function returning True when the item - should be displayed as active. - :param visible_when: Function returning True when this item - should be displayed. - :param dynamic_list_constructor: Function returning a list of - entries to be displayed by this item. Every object should - have 'text' and 'url' properties/dict elements. This property - will not be directly affect the menu system, but allows - other systems to use it while rendering. - :param kwargs: Additional arguments will be available as attributes - on registered :class:`MenuEntryMixin` instance. - - .. versionchanged:: 0.2.0 - The *kwargs* arguments. - """ - - def menu_decorator(f): - """Decorator of a view function that should be included in the menu.""" - if isinstance(app, Blueprint): - endpoint = app.name + "." + f.__name__ - before_first_request = app.before_app_first_request - else: - endpoint = f.__name__ - before_first_request = app.before_first_request - - expected = getfullargspec(f).args - - @before_first_request - def _register_menu_item(): - # str(path) allows path to be a string-convertible object - # that may be useful for delayed evaluation of path - item = current_menu.submenu(str(path)) - item.register( - endpoint, - text, - order, - endpoint_arguments_constructor=endpoint_arguments_constructor, - dynamic_list_constructor=dynamic_list_constructor, - active_when=active_when, - visible_when=visible_when, - expected_args=expected, - **kwargs, - ) - - return f - - return menu_decorator diff --git a/tests/test_core.py b/tests/test_core.py index c5e4dbe..4ab6129 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -14,7 +14,7 @@ from flask import Blueprint, request, url_for from pytest import raises -from flask_menu import Menu, current_menu, register_menu +from flask_menu import Menu, current_menu def test_simple_app_menu(app): @@ -77,64 +77,6 @@ def level3B(): assert item_2 == current_menu.submenu("level2").children[1] -def test_simple_app_register_menu(app): - """Test simple app.""" - - @app.route("/test") - @register_menu(app, ".", "Test") - def test(): - return "test" - - @app.route("/level2") - @register_menu(app, "level2", "Level 2") - def level2(): - return "level2" - - @app.route("/level3") - @register_menu(app, "level2.level3", "Level 3") - def level3(): - return "level3" - - @app.route("/level3B") - @register_menu(app, "level2.level3B", "Level 3B", order=1) - def level3B(): - return "level3B" - - with app.test_client() as c: - c.get("/test") - assert request.endpoint == "test" - assert current_menu.url == "/test" - assert current_menu.text == "Test" - assert current_menu.active - assert current_menu.submenu("level2").text == "Level 2" - assert not current_menu.submenu("level2").active - assert current_menu.submenu("missing", auto_create=False) is None - assert len(current_menu.list_path(".", ".level2.level3")) == 3 - assert current_menu.list_path(".", "missing") is None - assert current_menu.list_path("missing", ".level2.level3") is None - assert current_menu.list_path("level2.level3B", "level2.level3") is None - - with app.test_client() as c: - c.get("/level2") - assert current_menu.submenu("level2").active - - with app.test_client() as c: - c.get("/level3") - assert current_menu.submenu(".level2.level3").active - assert current_menu.submenu("level2.level3").active - - assert not current_menu.has_active_child(recursive=False) - assert current_menu.has_active_child() - assert current_menu.submenu("level2").has_active_child(recursive=False) - assert current_menu.submenu("level2").has_active_child() - - item_1 = current_menu.submenu("level2.level3") - item_2 = current_menu.submenu("level2.level3B") - assert item_1.order < item_2.order - assert item_1 == current_menu.submenu("level2").children[0] - assert item_2 == current_menu.submenu("level2").children[1] - - def test_blueprint_menu(app): """Test Blueprint.""" blueprint = Blueprint("foo", "foo", url_prefix="/foo") @@ -165,48 +107,23 @@ def bar(): assert current_menu.submenu("bar").active -def test_blueprint_register_menu(app): - """Test Blueprint.""" - blueprint = Blueprint("foo", "foo", url_prefix="/foo") - - @app.route("/test") - @register_menu(blueprint, ".", "Test") - def test(): - return "test" - - @blueprint.route("/bar") - @register_menu(blueprint, "bar", "Foo Bar") - def bar(): - return "bar" - - app.register_blueprint(blueprint) - - with app.test_client() as c: - c.get("/test") - assert request.endpoint == "test" - assert current_menu.text == "Test" - - with app.test_client() as c: - c.get("/foo/bar") - assert current_menu.submenu("bar").text == "Foo Bar" - assert current_menu.submenu("bar").active - - def test_visible_when(app): """Test visible when.""" + menu = app.extensions["menu"].root() + + menu.submenu(".always").register("always", "Always", visible_when=lambda: True) + menu.submenu(".never").register("never", "Never", visible_when=lambda: False) + menu.submenu(".normal").register("normal", "Normal") @app.route("/always") - @register_menu(app, "always", "Always", visible_when=lambda: True) def always(): return "never" @app.route("/never") - @register_menu(app, "never", "Never", visible_when=lambda: False) def never(): return "never" @app.route("/normal") - @register_menu(app, "normal", "Normal") def normal(): return "normal" @@ -238,19 +155,20 @@ def normal(): def test_visible_when_with_dynamic(app): """Test visible when with dynamic.""" + menu = app.extensions["menu"].root() + menu.submenu(".always").register("always", "Always", visible_when=lambda: True) + menu.submenu(".never").register("never", "Never", visible_when=lambda: False) + menu.submenu(".normal").register("normal", "Normal") @app.route("/always") - @register_menu(app, "always", "Always", visible_when=lambda: True) def always(): return "never" @app.route("/never") - @register_menu(app, "never", "Never", visible_when=lambda: False) def never(): return "never" @app.route("/normal//") - @register_menu(app, "normal", "Normal") def normal(id): return "normal" @@ -282,24 +200,25 @@ def normal(id): def test_active_item(app): """Test active_item method.""" + menu = app.extensions["menu"].root() + menu.submenu(".root").register("root", "root") + menu.submenu(".root.sub1.item1").register("sub1_item1", "Sub 1 - Item 1") + menu.submenu(".root.sub2.item1").register("sub2_item1", "Sub 2 - Item 1") + menu.submenu(".root.sub2.item2").register("sub2_item2", "Sub 2 - Item 2") @app.route("/") - @register_menu(app, "root", "root") def root(): return "root" @app.route("/sub1/item1") - @register_menu(app, "root.sub1.item1", "Sub 1 - Item 1") def sub1_item1(): return "sub1_item1" @app.route("/sub2/item1") - @register_menu(app, "root.sub2.item1", "Sub 2 - Item 1") def sub2_item1(): return "sub2_item1" @app.route("/sub2/item2") - @register_menu(app, "root.sub2.item2", "Sub 2 - Item 2") def sub2_item2(): return "sub2_item2" @@ -318,30 +237,30 @@ def sub2_item2(): def test_active_when(app): """Test active when.""" + menu = app.extensions["menu"].root() + menu.submenu(".root").register("root", "Root") + menu.submenu(".always").register("always", "Always", active_when=lambda: True) + menu.submenu(".never").register("never", "Never", active_when=lambda: False) + menu.submenu(".normal").register( + "normal", + "Normal", + active_when=lambda self: request.endpoint == self._endpoint, + ) @app.route("/") - @register_menu(app, "root", "Root") def root(): return "root" @app.route("/always") - @register_menu(app, "always", "Always", active_when=lambda: True) def always(): return "always" @app.route("/never") - @register_menu(app, "never", "Never", active_when=lambda: False) def never(): return "never" @app.route("/normal") @app.route("/normal/") - @register_menu( - app, - "normal", - "Normal", - active_when=lambda self: request.endpoint == self._endpoint, - ) def normal(path=None): return "normal" @@ -388,10 +307,8 @@ def assert_msg(active_is): def test_dynamic_url(app): """Test dynamic url.""" - - @app.route("//") - @register_menu( - app, + menu = app.extensions["menu"].root() + menu.submenu(".test").register( "test", "Test", endpoint_arguments_constructor=lambda: { @@ -399,6 +316,8 @@ def test_dynamic_url(app): "name": request.view_args["name"], }, ) + + @app.route("//") def test(id, name): return str(id) + ":" + name @@ -414,9 +333,10 @@ def test(id, name): def test_kwargs(app): """Test optional arguments.""" count = 5 + menu = app.extensions["menu"].root() + menu.submenu("test").register("test", "Test", count=count) @app.route("/test") - @register_menu(app, "test", "Test", count=count) def test(): return "count" @@ -472,13 +392,15 @@ def test_dynamic_list_constructor(app): def get_menu_items(): return bar + menu = app.extensions["menu"].root() + menu.submenu(".foo").register("foo", "foo", dynamic_list_constructor=get_menu_items) + menu.submenu(".other").register("other", "Other") + @app.route("/") - @register_menu(app, "foo", "foo", dynamic_list_constructor=get_menu_items) def foo(): return "foo" @app.route("/other") - @register_menu(app, "other", "Other") def other(): return "other" @@ -499,6 +421,17 @@ def test_app_without_existing_extensions(app): def test_has_visible_child(app): """Test has visible child.""" + menu = app.extensions["menu"].root() + menu.submenu(".one.four").register( + "one_four", "One Four", visible_when=lambda: False + ) + menu.submenu(".six.seven").register( + "six_seven", "Six Seven", visible_when=lambda: False + ) + menu.submenu(".six.seven.eight").register("six_seven_eight", "Six Seven Eight") + menu.submenu(".two").register("two", "Trow") + menu.submenu(".two.three").register("two_three", "Two Three") + menu.submenu(".two.three.five").register("two_three_five", "Two Three Five") @app.route("/one") def one(): @@ -506,7 +439,6 @@ def one(): # This item should never be visible. @app.route("/one/four") - @register_menu(app, "one.four", "One Four", visible_when=lambda: False) def one_four(): return "one_four" @@ -516,27 +448,22 @@ def six(): # This item should never be visible. @app.route("/six/seven") - @register_menu(app, "six.seven", "Six Seven", visible_when=lambda: False) def six_seven(): return "six_seven" @app.route("/six/seven/eight") - @register_menu(app, "six.seven.eight", "Six Seven Eight") def six_seven_eight(): return "six_seven_eight" @app.route("/two") - @register_menu(app, "two", "Trow") def two(): return "two" @app.route("/two/three") - @register_menu(app, "two.three", "Two Three") def two_three(): return "two_three" @app.route("/two/three/five") - @register_menu(app, "two.three.five", "Two Three Five") def two_three_five(): return "two_three_five" @@ -641,14 +568,15 @@ def assert_msg(visible_is): def test_active_checks_segment_not_prefix(app): """Test active checks segment not prefix.""" + menu = app.extensions["menu"].root() + menu.submenu(".object").register("object", "Object") + menu.submenu(".objects").register("objects", "Objects") @app.route("/object") - @register_menu(app, "object", "Object") def object(): return "object" @app.route("/objects") - @register_menu(app, "objects", "Objects") def objects(): return "objects"