-
-
Notifications
You must be signed in to change notification settings - Fork 187
/
Copy pathtest_repl.py
172 lines (127 loc) · 4.48 KB
/
test_repl.py
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# -*- coding: utf-8 -*-
"""
jishaku.repl internal test
~~~~~~~~~~~~~~~~~~~~~~~~~~
:copyright: (c) 2021 Devon (scarletcafe) R
:license: MIT, see LICENSE for more details.
"""
import inspect
import random
import typing
import pytest
from jishaku.repl import AsyncCodeExecutor, Scope, get_parent_var, get_var_dict_from_ctx
from tests.utils import mock_ctx
def upper_method():
return get_parent_var('hidden_variable')
async def add_numbers(one: int, two: int) -> int:
return one + two
@pytest.fixture(scope="module")
def scope():
return Scope(
{
"add_numbers": add_numbers,
"placement": 81
},
{
"placement_local": 18
}
)
def test_scope_var():
for _ in range(10):
hidden_variable = random.randint(0, 1000000)
test = upper_method()
assert hidden_variable == test
del hidden_variable
test = upper_method()
assert test is None
assert get_parent_var('pytest', global_ok=True) == pytest
@pytest.mark.parametrize(
("code", "expected"),
[
('3 + 4', [7]),
('return 3 + 9', [12]),
('yield 30; yield 40', [30, 40]),
('yield 60; 70', [60, 70]),
('90; 100', [100]),
('eval("""\n77 + 22\n""")', [99]),
]
)
@pytest.mark.asyncio
async def test_executor_basic(code: str, expected: typing.List[int]):
return_data: list[int] = []
async for result in AsyncCodeExecutor(code):
return_data.append(result)
assert len(return_data) == len(expected)
for a, b in zip(return_data, expected):
assert a == b
@pytest.mark.parametrize(
("code", "expected", "arg_dict"),
[
("", [None], None),
("# this is a comment", [None], None),
("b = 12 + 82", [None], None),
("b", [94], None),
("c = placement + 7; c", [88], None),
(
"_cool_data + _not_so_cool",
[445],
{
'_cool_data': 45,
'_not_so_cool': 400
}
),
pytest.param(
"_cool_data", [45], None,
marks=pytest.mark.xfail(raises=NameError, strict=True)
),
("await add_numbers(10, 12)", [22], None)
]
)
@pytest.mark.asyncio
async def test_executor_advanced(code: str, expected: typing.List[typing.Optional[int]], arg_dict: typing.Optional[typing.Dict[str, int]], scope: Scope):
return_data: list[int | None] = []
async for result in AsyncCodeExecutor(code, scope, arg_dict=arg_dict):
return_data.append(result)
assert len(return_data) == len(expected)
for a, b in zip(return_data, expected):
assert a == b
if arg_dict:
scope.clear_intersection(arg_dict)
@pytest.mark.asyncio
async def test_scope_copy(scope: Scope):
scope2 = Scope()
scope2.update(scope)
assert scope.globals == scope2.globals, "Checking scope globals copied"
assert scope.locals == scope2.locals, "Checking scope locals copied"
insert_dict = {'e': 7}
scope.update_locals(insert_dict)
assert 'e' in scope.locals, "Checking scope locals updated"
assert 'e' not in scope2.locals, "Checking scope clone locals not updated"
scope.clear_intersection(insert_dict)
assert 'e' not in scope.locals, "Checking locals intersection cleared"
scope.update_globals(insert_dict)
assert 'e' in scope.globals, "Checking scope globals updated"
assert 'e' not in scope2.globals, "Checking scope clone globals not updated"
scope.clear_intersection(insert_dict)
assert 'e' not in scope.globals, "Checking globals intersection cleared"
@pytest.mark.asyncio
async def test_executor_builtins(scope: Scope):
codeblock = inspect.cleandoc("""
def ensure_builtins():
return ValueError
""")
return_data: list[None] = []
async for result in AsyncCodeExecutor(codeblock, scope):
return_data.append(result)
assert len(return_data) == 1
assert return_data[0] is None
assert 'ensure_builtins' in scope.globals, "Checking function remains defined"
assert callable(scope.globals['ensure_builtins']), "Checking defined is callable"
assert scope.globals['ensure_builtins']() == ValueError, "Checking defined return consistent"
@pytest.mark.asyncio
async def test_var_dict(scope: Scope):
with mock_ctx() as ctx:
scope.update_globals(get_var_dict_from_ctx(ctx))
assert scope.globals['_ctx'] is ctx
assert scope.globals['_bot'] is ctx.bot
assert scope.globals['_message'] is ctx.message