From 4f1a3b5f9ad05aa7b08715d48909a2b06ee2fcb1 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 18:35:31 +0200 Subject: Adding upstream version 3.0.43. Signed-off-by: Daniel Baumann --- tests/test_filter.py | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 tests/test_filter.py (limited to 'tests/test_filter.py') diff --git a/tests/test_filter.py b/tests/test_filter.py new file mode 100644 index 0000000..f7184c2 --- /dev/null +++ b/tests/test_filter.py @@ -0,0 +1,131 @@ +from __future__ import annotations + +import pytest + +from prompt_toolkit.filters import Always, Condition, Filter, Never, to_filter +from prompt_toolkit.filters.base import _AndList, _OrList + + +def test_never(): + assert not Never()() + + +def test_always(): + assert Always()() + + +def test_invert(): + assert not (~Always())() + assert ~Never()() + + c = ~Condition(lambda: False) + assert c() + + +def test_or(): + for a in (True, False): + for b in (True, False): + c1 = Condition(lambda: a) + c2 = Condition(lambda: b) + c3 = c1 | c2 + + assert isinstance(c3, Filter) + assert c3() == a or b + + +def test_and(): + for a in (True, False): + for b in (True, False): + c1 = Condition(lambda: a) + c2 = Condition(lambda: b) + c3 = c1 & c2 + + assert isinstance(c3, Filter) + assert c3() == (a and b) + + +def test_nested_and(): + for a in (True, False): + for b in (True, False): + for c in (True, False): + c1 = Condition(lambda: a) + c2 = Condition(lambda: b) + c3 = Condition(lambda: c) + c4 = (c1 & c2) & c3 + + assert isinstance(c4, Filter) + assert c4() == (a and b and c) + + +def test_nested_or(): + for a in (True, False): + for b in (True, False): + for c in (True, False): + c1 = Condition(lambda: a) + c2 = Condition(lambda: b) + c3 = Condition(lambda: c) + c4 = (c1 | c2) | c3 + + assert isinstance(c4, Filter) + assert c4() == (a or b or c) + + +def test_to_filter(): + f1 = to_filter(True) + f2 = to_filter(False) + f3 = to_filter(Condition(lambda: True)) + f4 = to_filter(Condition(lambda: False)) + + assert isinstance(f1, Filter) + assert isinstance(f2, Filter) + assert isinstance(f3, Filter) + assert isinstance(f4, Filter) + assert f1() + assert not f2() + assert f3() + assert not f4() + + with pytest.raises(TypeError): + to_filter(4) + + +def test_filter_cache_regression_1(): + # See: https://github.com/prompt-toolkit/python-prompt-toolkit/issues/1729 + + cond = Condition(lambda: True) + + # The use of a `WeakValueDictionary` caused this following expression to + # fail. The problem is that the nested `(a & a)` expression gets garbage + # collected between the two statements and is removed from our cache. + x = (cond & cond) & cond + y = (cond & cond) & cond + assert x == y + + +def test_filter_cache_regression_2(): + cond1 = Condition(lambda: True) + cond2 = Condition(lambda: True) + cond3 = Condition(lambda: True) + + x = (cond1 & cond2) & cond3 + y = (cond1 & cond2) & cond3 + assert x == y + + +def test_filter_remove_duplicates(): + cond1 = Condition(lambda: True) + cond2 = Condition(lambda: True) + + # When a condition is appended to itself using an `&` or `|` operator, it + # should not be present twice. Having it twice in the `_AndList` or + # `_OrList` will make them more expensive to evaluate. + + assert isinstance(cond1 & cond1, Condition) + assert isinstance(cond1 & cond1 & cond1, Condition) + assert isinstance(cond1 & cond1 & cond2, _AndList) + assert len((cond1 & cond1 & cond2).filters) == 2 + + assert isinstance(cond1 | cond1, Condition) + assert isinstance(cond1 | cond1 | cond1, Condition) + assert isinstance(cond1 | cond1 | cond2, _OrList) + assert len((cond1 | cond1 | cond2).filters) == 2 -- cgit v1.2.3