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
|
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
|