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
|
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE in the project root
# for license information.
"""Pattern matching for recursive Python data structures.
Usage::
from tests.patterns import some
assert object() == some.object
assert None == some.object
assert None != some.thing
assert None == ~some.thing # inverse
assert None == some.thing | None
assert 123 == some.thing.in_range(0, 200)
assert "abc" == some.thing.such_that(lambda s: s.startswith("ab"))
xs = []
assert xs == some.specific_object(xs) # xs is xs
assert xs != some.specific_object([]) # xs is not []
assert Exception() == some.instanceof(Exception)
assert 123 == some.instanceof((int, str))
assert "abc" == some.instanceof((int, str))
assert True == some.bool
assert 123.456 == some.number
assert 123 == some.int
assert Exception() == some.error
assert object() == some.object.same_as(object())
assert b"abc" == some.bytes
assert "abc" == some.str
assert b"abc" != some.str
assert "abbc" == some.str.starting_with("ab")
assert "abbc" == some.str.ending_with("bc")
assert "abbc" == some.str.containing("bb")
assert "abbc" == some.str.matching(r".(b+).")
assert "abbc" != some.str.matching(r"ab")
assert "abbc" != some.str.matching(r"bc")
if sys.platform == "win32":
assert "\\Foo\\Bar" == some.path("/foo/bar")
else:
assert "/Foo/Bar" != some.path("/foo/bar")
assert {
"bool": True,
"list": [None, True, 123],
"dict": {
"int": 123,
"str": "abc",
},
} == some.dict.containing({
"list": [None, some.bool, some.int | some.str],
"dict": some.dict.containing({
"int": some.int.in_range(100, 200),
})
})
"""
__all__ = [
"bool",
"bytes",
"dap",
"dict",
"error",
"instanceof",
"int",
"list",
"number",
"path",
"str",
"thing",
"tuple",
]
import builtins
import numbers
import re
from tests.patterns import _impl
object = _impl.Object()
thing = _impl.Thing()
instanceof = _impl.InstanceOf
path = _impl.Path
bool = instanceof(builtins.bool)
number = instanceof(numbers.Real, "number")
int = instanceof(numbers.Integral, "int")
tuple = instanceof(builtins.tuple)
error = instanceof(Exception)
bytes = instanceof(builtins.bytes)
bytes.starting_with = lambda prefix: bytes.matching(
re.escape(prefix) + b".*", re.DOTALL
)
bytes.ending_with = lambda suffix: bytes.matching(b".*" + re.escape(suffix), re.DOTALL)
bytes.containing = lambda sub: bytes.matching(b".*" + re.escape(sub) + b".*", re.DOTALL)
str = instanceof(builtins.str)
str.starting_with = lambda prefix: str.matching(re.escape(prefix) + ".*", re.DOTALL)
str.ending_with = lambda suffix: str.matching(".*" + re.escape(suffix), re.DOTALL)
str.containing = lambda sub: str.matching(".*" + re.escape(sub) + ".*", re.DOTALL)
list = instanceof(builtins.list)
list.containing = _impl.ListContaining
dict = instanceof(builtins.dict)
dict.containing = _impl.DictContaining
# Set in __init__.py to avoid circular dependency.
dap = None
|