|
1 | 1 | # -*- coding: utf-8 -*- |
2 | | -"""Utilities for writing tests.""" |
| 2 | +"""Utilities for writing tests. |
| 3 | +
|
| 4 | +See also `unpythonic.test.fixtures` for the high-level machinery. |
| 5 | +""" |
3 | 6 |
|
4 | 7 | from macropy.core.quotes import macros, q, u, ast_literal, name |
5 | 8 | from macropy.core.hquotes import macros, hq # noqa: F811, F401 |
6 | 9 | from macropy.core import unparse |
7 | 10 |
|
8 | | -from ast import Tuple, Str, copy_location |
| 11 | +from ast import Tuple, Str, Subscript, Name, Call, copy_location |
9 | 12 |
|
10 | 13 | from ..dynassign import dyn # for MacroPy's gen_sym |
11 | 14 | from ..misc import callsite_filename |
12 | 15 | from ..conditions import cerror, handlers, restarts, invoke |
13 | 16 | from ..collections import box, unbox |
14 | 17 | from ..symbol import sym |
15 | 18 |
|
| 19 | +from .util import isx |
| 20 | + |
16 | 21 | from ..test import fixtures |
17 | 22 |
|
| 23 | +# ----------------------------------------------------------------------------- |
| 24 | +# Helper for other macros to detect uses of the ones we define here. |
| 25 | + |
| 26 | +# Note the unexpanded `error[]` macro is distinguishable from a call to |
| 27 | +# the function `unpythonic.conditions.error`, because a macro invocation |
| 28 | +# is an `ast.Subscript`, whereas a function call is an `ast.Call`. |
| 29 | +_test_macro_names = ["test", "test_signals", "test_raises", "error", "fail"] |
| 30 | +_test_function_names = ["unpythonic_assert", |
| 31 | + "unpythonic_assert_signals", |
| 32 | + "unpythonic_assert_raises"] |
| 33 | +def istestmacro(tree): |
| 34 | + """Return whether `tree` is an invocation of a testing macro. |
| 35 | +
|
| 36 | + Expanded or unexpanded doesn't matter; this is currently provided |
| 37 | + so that other macros can detect and skip subtrees that invoke a test. |
| 38 | + """ |
| 39 | + def isunexpandedtestmacro(tree): |
| 40 | + return (type(tree) is Subscript and |
| 41 | + type(tree.value) is Name and |
| 42 | + tree.value.id in _test_macro_names) |
| 43 | + def isexpandedtestmacro(tree): |
| 44 | + return (type(tree) is Call and |
| 45 | + any(isx(tree.func, fname, accept_attr=False) |
| 46 | + for fname in _test_function_names)) |
| 47 | + return isunexpandedtestmacro(tree) or isexpandedtestmacro(tree) |
| 48 | + |
18 | 49 | # ----------------------------------------------------------------------------- |
19 | 50 | # Regular code, no macros yet. |
20 | 51 |
|
|
0 commit comments