genlayer-test 0.7.0__py3-none-any.whl → 0.9.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {genlayer_test-0.7.0.dist-info → genlayer_test-0.9.0.dist-info}/METADATA +245 -4
- genlayer_test-0.9.0.dist-info/RECORD +38 -0
- {genlayer_test-0.7.0.dist-info → genlayer_test-0.9.0.dist-info}/top_level.txt +0 -1
- gltest/__init__.py +3 -0
- gltest/types.py +12 -1
- gltest/validators/__init__.py +3 -0
- gltest/validators/validator_factory.py +136 -0
- gltest_cli/config/constants.py +7 -0
- gltest_cli/config/plugin.py +22 -4
- gltest_cli/config/types.py +81 -46
- gltest_cli/config/user.py +95 -7
- genlayer_test-0.7.0.dist-info/RECORD +0 -79
- tests/__init__.py +0 -0
- tests/conftest.py +0 -1
- tests/examples/contracts/football_prediction_market.py +0 -100
- tests/examples/contracts/intelligent_oracle.py +0 -370
- tests/examples/contracts/intelligent_oracle_factory.py +0 -49
- tests/examples/contracts/invalid_deploy.py +0 -10
- tests/examples/contracts/llm_erc20.py +0 -70
- tests/examples/contracts/log_indexer.py +0 -69
- tests/examples/contracts/multi_file_contract/__init__.py +0 -24
- tests/examples/contracts/multi_file_contract/other.py +0 -14
- tests/examples/contracts/multi_read_erc20.py +0 -29
- tests/examples/contracts/multi_tenant_storage.py +0 -51
- tests/examples/contracts/read_erc20.py +0 -19
- tests/examples/contracts/simple_time_contract.py +0 -85
- tests/examples/contracts/storage.py +0 -23
- tests/examples/contracts/user_storage.py +0 -25
- tests/examples/contracts/wizard_of_coin.py +0 -57
- tests/examples/tests/test_football_prediction_market.py +0 -38
- tests/examples/tests/test_intelligent_oracle_factory.py +0 -162
- tests/examples/tests/test_invalid_deploy.py +0 -24
- tests/examples/tests/test_llm_erc20.py +0 -60
- tests/examples/tests/test_llm_erc20_analyze.py +0 -54
- tests/examples/tests/test_log_indexer.py +0 -76
- tests/examples/tests/test_multi_file_contract.py +0 -15
- tests/examples/tests/test_multi_read_erc20.py +0 -103
- tests/examples/tests/test_multi_tenant_storage.py +0 -76
- tests/examples/tests/test_read_erc20.py +0 -38
- tests/examples/tests/test_simple_time_contract.py +0 -90
- tests/examples/tests/test_storage.py +0 -26
- tests/examples/tests/test_user_storage.py +0 -87
- tests/examples/tests/test_wizard_of_coin.py +0 -27
- tests/gltest/__init__.py +0 -0
- tests/gltest/artifact/__init__.py +0 -0
- tests/gltest/artifact/contracts/duplicate_ic_contract_1.py +0 -22
- tests/gltest/artifact/contracts/duplicate_ic_contract_2.py +0 -22
- tests/gltest/artifact/contracts/not_ic_contract.py +0 -22
- tests/gltest/artifact/test_contract_definition.py +0 -55
- tests/gltest/assertions/test_assertions.py +0 -344
- tests/gltest_cli/__init__.py +0 -0
- tests/gltest_cli/config/test_config_integration.py +0 -432
- tests/gltest_cli/config/test_general_config.py +0 -406
- tests/gltest_cli/config/test_plugin.py +0 -290
- tests/gltest_cli/config/test_user.py +0 -411
- {genlayer_test-0.7.0.dist-info → genlayer_test-0.9.0.dist-info}/WHEEL +0 -0
- {genlayer_test-0.7.0.dist-info → genlayer_test-0.9.0.dist-info}/entry_points.txt +0 -0
- {genlayer_test-0.7.0.dist-info → genlayer_test-0.9.0.dist-info}/licenses/LICENSE +0 -0
gltest_cli/config/types.py
CHANGED
@@ -1,11 +1,16 @@
|
|
1
|
-
from enum import Enum
|
2
1
|
from dataclasses import dataclass, field
|
3
2
|
from pathlib import Path
|
4
3
|
from typing import Dict, List, Optional
|
5
4
|
from genlayer_py.chains import localnet, studionet, testnet_asimov
|
6
5
|
from genlayer_py.types import GenLayerChain
|
7
|
-
from urllib.parse import urlparse
|
8
6
|
from gltest_cli.config.constants import PRECONFIGURED_NETWORKS
|
7
|
+
from gltest_cli.config.constants import (
|
8
|
+
DEFAULT_WAIT_INTERVAL,
|
9
|
+
DEFAULT_WAIT_RETRIES,
|
10
|
+
DEFAULT_TEST_WITH_MOCKS,
|
11
|
+
DEFAULT_LEADER_ONLY,
|
12
|
+
CHAINS,
|
13
|
+
)
|
9
14
|
|
10
15
|
|
11
16
|
@dataclass
|
@@ -18,6 +23,7 @@ class PluginConfig:
|
|
18
23
|
network_name: Optional[str] = None
|
19
24
|
test_with_mocks: bool = False
|
20
25
|
leader_only: bool = False
|
26
|
+
chain_type: Optional[str] = None
|
21
27
|
|
22
28
|
|
23
29
|
@dataclass
|
@@ -27,6 +33,10 @@ class NetworkConfigData:
|
|
27
33
|
accounts: Optional[List[str]] = None
|
28
34
|
from_account: Optional[str] = None
|
29
35
|
leader_only: bool = False
|
36
|
+
default_wait_interval: Optional[int] = None
|
37
|
+
default_wait_retries: Optional[int] = None
|
38
|
+
test_with_mocks: bool = False
|
39
|
+
chain_type: Optional[str] = None
|
30
40
|
|
31
41
|
def __post_init__(self):
|
32
42
|
if self.id is not None and not isinstance(self.id, int):
|
@@ -40,6 +50,20 @@ class NetworkConfigData:
|
|
40
50
|
raise ValueError("accounts must be strings")
|
41
51
|
if self.from_account is not None and not isinstance(self.from_account, str):
|
42
52
|
raise ValueError("from_account must be a string")
|
53
|
+
if not isinstance(self.leader_only, bool):
|
54
|
+
raise TypeError("leader_only must be a boolean")
|
55
|
+
if self.default_wait_interval is not None and not isinstance(
|
56
|
+
self.default_wait_interval, int
|
57
|
+
):
|
58
|
+
raise ValueError("default_wait_interval must be an integer")
|
59
|
+
if self.default_wait_retries is not None and not isinstance(
|
60
|
+
self.default_wait_retries, int
|
61
|
+
):
|
62
|
+
raise ValueError("default_wait_retries must be an integer")
|
63
|
+
if not isinstance(self.test_with_mocks, bool):
|
64
|
+
raise TypeError("test_with_mocks must be a boolean")
|
65
|
+
if self.chain_type is not None and not isinstance(self.chain_type, str):
|
66
|
+
raise ValueError("chain_type must be a string")
|
43
67
|
|
44
68
|
|
45
69
|
@dataclass
|
@@ -130,50 +154,69 @@ class GeneralConfig:
|
|
130
154
|
return self.user_config.networks[network_name].accounts
|
131
155
|
return self.user_config.networks[self.user_config.default_network].accounts
|
132
156
|
|
133
|
-
def
|
157
|
+
def get_chain_type(self) -> str:
|
158
|
+
# If chain_type is explicitly set via CLI, use it
|
159
|
+
if self.plugin_config.chain_type is not None:
|
160
|
+
if self.plugin_config.chain_type not in CHAINS:
|
161
|
+
raise ValueError(
|
162
|
+
f"Unknown chain type: {self.plugin_config.chain_type}. "
|
163
|
+
f"Valid values: {', '.join(CHAINS)}"
|
164
|
+
)
|
165
|
+
return self.plugin_config.chain_type
|
166
|
+
|
134
167
|
network_name = self.get_network_name()
|
135
168
|
if network_name not in self.user_config.networks:
|
136
169
|
raise ValueError(
|
137
170
|
f"Unknown network: {network_name}, possible values: {self.get_networks_keys()}"
|
138
171
|
)
|
172
|
+
network_config = self.user_config.networks[network_name]
|
173
|
+
# For preconfigured networks, use its chain type
|
174
|
+
if network_name in PRECONFIGURED_NETWORKS:
|
175
|
+
chain_type = network_config.chain_type
|
176
|
+
else:
|
177
|
+
# For custom networks, chain_type field is required
|
178
|
+
chain_type = network_config.chain_type
|
179
|
+
if not chain_type:
|
180
|
+
raise ValueError(
|
181
|
+
f"Custom network {network_name} must specify a 'chain_type' field. "
|
182
|
+
f"Valid values: {', '.join(CHAINS)}"
|
183
|
+
)
|
184
|
+
|
185
|
+
if chain_type not in CHAINS:
|
186
|
+
raise ValueError(
|
187
|
+
f"Unknown chain type: {chain_type}. "
|
188
|
+
f"Valid values: {', '.join(CHAINS)}"
|
189
|
+
)
|
190
|
+
return chain_type
|
139
191
|
|
140
|
-
|
141
|
-
|
192
|
+
def get_chain(self) -> GenLayerChain:
|
193
|
+
chain_map = {
|
142
194
|
"localnet": localnet,
|
143
195
|
"studionet": studionet,
|
144
196
|
"testnet_asimov": testnet_asimov,
|
145
197
|
}
|
146
|
-
|
147
|
-
|
148
|
-
return chain_map_by_name[network_name]
|
149
|
-
|
150
|
-
if network_name in PRECONFIGURED_NETWORKS:
|
151
|
-
raise ValueError(
|
152
|
-
f"Network {network_name} should be handled by reserved mapping"
|
153
|
-
)
|
154
|
-
|
155
|
-
# Custom networks
|
156
|
-
chain_map_by_id = {
|
157
|
-
61999: localnet,
|
158
|
-
4221: testnet_asimov,
|
159
|
-
}
|
160
|
-
network_id = self.user_config.networks[network_name].id
|
161
|
-
if network_id not in chain_map_by_id:
|
162
|
-
known = ", ".join(map(str, chain_map_by_id.keys()))
|
163
|
-
raise ValueError(
|
164
|
-
f"Unknown network id: {network_id}, possible values: {known}"
|
165
|
-
)
|
166
|
-
return chain_map_by_id[network_id]
|
198
|
+
chain_type = self.get_chain_type()
|
199
|
+
return chain_map[chain_type]
|
167
200
|
|
168
201
|
def get_default_wait_interval(self) -> int:
|
169
202
|
if self.plugin_config.default_wait_interval is not None:
|
170
203
|
return self.plugin_config.default_wait_interval
|
171
|
-
|
204
|
+
network_name = self.get_network_name()
|
205
|
+
if network_name in self.user_config.networks:
|
206
|
+
network_config = self.user_config.networks[network_name]
|
207
|
+
if network_config.default_wait_interval is not None:
|
208
|
+
return network_config.default_wait_interval
|
209
|
+
return DEFAULT_WAIT_INTERVAL
|
172
210
|
|
173
211
|
def get_default_wait_retries(self) -> int:
|
174
212
|
if self.plugin_config.default_wait_retries is not None:
|
175
213
|
return self.plugin_config.default_wait_retries
|
176
|
-
|
214
|
+
network_name = self.get_network_name()
|
215
|
+
if network_name in self.user_config.networks:
|
216
|
+
network_config = self.user_config.networks[network_name]
|
217
|
+
if network_config.default_wait_retries is not None:
|
218
|
+
return network_config.default_wait_retries
|
219
|
+
return DEFAULT_WAIT_RETRIES
|
177
220
|
|
178
221
|
def get_network_name(self) -> str:
|
179
222
|
if self.plugin_config.network_name is not None:
|
@@ -181,7 +224,13 @@ class GeneralConfig:
|
|
181
224
|
return self.user_config.default_network
|
182
225
|
|
183
226
|
def get_test_with_mocks(self) -> bool:
|
184
|
-
|
227
|
+
if self.plugin_config.test_with_mocks:
|
228
|
+
return True
|
229
|
+
network_name = self.get_network_name()
|
230
|
+
if network_name in self.user_config.networks:
|
231
|
+
network_config = self.user_config.networks[network_name]
|
232
|
+
return network_config.test_with_mocks
|
233
|
+
return DEFAULT_TEST_WITH_MOCKS
|
185
234
|
|
186
235
|
def get_leader_only(self) -> bool:
|
187
236
|
if self.plugin_config.leader_only:
|
@@ -190,24 +239,10 @@ class GeneralConfig:
|
|
190
239
|
if network_name in self.user_config.networks:
|
191
240
|
network_config = self.user_config.networks[network_name]
|
192
241
|
return network_config.leader_only
|
193
|
-
return
|
242
|
+
return DEFAULT_LEADER_ONLY
|
194
243
|
|
195
244
|
def check_local_rpc(self) -> bool:
|
196
|
-
|
197
|
-
rpc_url = self.get_rpc_url()
|
198
|
-
domain = urlparse(rpc_url).netloc.split(":")[0] # Extract domain without port
|
199
|
-
return domain in SUPPORTED_RPC_DOMAINS
|
245
|
+
return self.get_chain_type() == "localnet"
|
200
246
|
|
201
247
|
def check_studio_based_rpc(self) -> bool:
|
202
|
-
|
203
|
-
rpc_url = self.get_rpc_url()
|
204
|
-
domain = urlparse(rpc_url).netloc.split(":")[0] # Extract domain without port
|
205
|
-
|
206
|
-
if domain in SUPPORTED_RPC_DOMAINS:
|
207
|
-
return True
|
208
|
-
|
209
|
-
# Check .genlayer.com or .genlayerlabs.com subdomains
|
210
|
-
if domain.endswith(".genlayer.com") or domain.endswith(".genlayerlabs.com"):
|
211
|
-
return True
|
212
|
-
|
213
|
-
return False
|
248
|
+
return self.get_chain_type() == "studionet"
|
gltest_cli/config/user.py
CHANGED
@@ -4,6 +4,7 @@ import re
|
|
4
4
|
from dotenv import load_dotenv
|
5
5
|
from pathlib import Path
|
6
6
|
from functools import lru_cache
|
7
|
+
from dataclasses import replace
|
7
8
|
from gltest.accounts import create_accounts
|
8
9
|
from gltest_cli.config.constants import (
|
9
10
|
GLTEST_CONFIG_FILE,
|
@@ -12,12 +13,27 @@ from gltest_cli.config.constants import (
|
|
12
13
|
DEFAULT_CONTRACTS_DIR,
|
13
14
|
DEFAULT_ARTIFACTS_DIR,
|
14
15
|
PRECONFIGURED_NETWORKS,
|
16
|
+
DEFAULT_WAIT_INTERVAL,
|
17
|
+
DEFAULT_WAIT_RETRIES,
|
18
|
+
DEFAULT_TEST_WITH_MOCKS,
|
19
|
+
DEFAULT_LEADER_ONLY,
|
20
|
+
CHAINS,
|
15
21
|
)
|
16
22
|
from genlayer_py.chains import localnet, studionet, testnet_asimov
|
17
23
|
from gltest_cli.config.types import UserConfig, NetworkConfigData, PathConfig
|
18
24
|
|
19
25
|
VALID_ROOT_KEYS = ["networks", "paths", "environment"]
|
20
|
-
VALID_NETWORK_KEYS = [
|
26
|
+
VALID_NETWORK_KEYS = [
|
27
|
+
"id",
|
28
|
+
"url",
|
29
|
+
"accounts",
|
30
|
+
"from",
|
31
|
+
"leader_only",
|
32
|
+
"default_wait_interval",
|
33
|
+
"default_wait_retries",
|
34
|
+
"test_with_mocks",
|
35
|
+
"chain_type",
|
36
|
+
]
|
21
37
|
VALID_PATHS_KEYS = ["contracts", "artifacts"]
|
22
38
|
|
23
39
|
|
@@ -32,21 +48,33 @@ def get_default_user_config() -> UserConfig:
|
|
32
48
|
url=localnet.rpc_urls["default"]["http"][0],
|
33
49
|
accounts=accounts_private_keys,
|
34
50
|
from_account=accounts_private_keys[0],
|
35
|
-
leader_only=
|
51
|
+
leader_only=DEFAULT_LEADER_ONLY,
|
52
|
+
default_wait_interval=DEFAULT_WAIT_INTERVAL,
|
53
|
+
default_wait_retries=DEFAULT_WAIT_RETRIES,
|
54
|
+
test_with_mocks=DEFAULT_TEST_WITH_MOCKS,
|
55
|
+
chain_type="localnet",
|
36
56
|
),
|
37
57
|
"studionet": NetworkConfigData(
|
38
58
|
id=studionet.id,
|
39
59
|
url=studionet.rpc_urls["default"]["http"][0],
|
40
60
|
accounts=accounts_private_keys,
|
41
61
|
from_account=accounts_private_keys[0],
|
42
|
-
leader_only=
|
62
|
+
leader_only=DEFAULT_LEADER_ONLY,
|
63
|
+
default_wait_interval=DEFAULT_WAIT_INTERVAL,
|
64
|
+
default_wait_retries=DEFAULT_WAIT_RETRIES,
|
65
|
+
test_with_mocks=DEFAULT_TEST_WITH_MOCKS,
|
66
|
+
chain_type="studionet",
|
43
67
|
),
|
44
68
|
"testnet_asimov": NetworkConfigData(
|
45
69
|
id=testnet_asimov.id,
|
46
70
|
url=testnet_asimov.rpc_urls["default"]["http"][0],
|
47
71
|
accounts=None,
|
48
72
|
from_account=None,
|
49
|
-
leader_only=
|
73
|
+
leader_only=DEFAULT_LEADER_ONLY,
|
74
|
+
default_wait_interval=DEFAULT_WAIT_INTERVAL,
|
75
|
+
default_wait_retries=DEFAULT_WAIT_RETRIES,
|
76
|
+
test_with_mocks=DEFAULT_TEST_WITH_MOCKS,
|
77
|
+
chain_type="testnet_asimov",
|
50
78
|
),
|
51
79
|
}
|
52
80
|
|
@@ -121,7 +149,34 @@ def validate_network_config(network_name: str, network_config: dict):
|
|
121
149
|
):
|
122
150
|
raise ValueError(f"network {network_name} leader_only must be a boolean")
|
123
151
|
|
124
|
-
|
152
|
+
if "default_wait_interval" in network_config and not isinstance(
|
153
|
+
network_config["default_wait_interval"], int
|
154
|
+
):
|
155
|
+
raise ValueError(
|
156
|
+
f"network {network_name} default_wait_interval must be an integer"
|
157
|
+
)
|
158
|
+
|
159
|
+
if "default_wait_retries" in network_config and not isinstance(
|
160
|
+
network_config["default_wait_retries"], int
|
161
|
+
):
|
162
|
+
raise ValueError(
|
163
|
+
f"network {network_name} default_wait_retries must be an integer"
|
164
|
+
)
|
165
|
+
|
166
|
+
if "test_with_mocks" in network_config and not isinstance(
|
167
|
+
network_config["test_with_mocks"], bool
|
168
|
+
):
|
169
|
+
raise ValueError(f"network {network_name} test_with_mocks must be a boolean")
|
170
|
+
|
171
|
+
if "chain_type" in network_config:
|
172
|
+
if not isinstance(network_config["chain_type"], str):
|
173
|
+
raise ValueError(f"network {network_name} chain_type must be a string")
|
174
|
+
if network_config["chain_type"] not in CHAINS:
|
175
|
+
raise ValueError(
|
176
|
+
f"network {network_name} chain_type must be one of: {', '.join(CHAINS)}"
|
177
|
+
)
|
178
|
+
|
179
|
+
# For non-preconfigured networks, url, accounts, and chain are required
|
125
180
|
if network_name not in PRECONFIGURED_NETWORKS:
|
126
181
|
if "id" not in network_config:
|
127
182
|
raise ValueError(f"network {network_name} must have an id")
|
@@ -129,6 +184,10 @@ def validate_network_config(network_name: str, network_config: dict):
|
|
129
184
|
raise ValueError(f"network {network_name} must have a url")
|
130
185
|
if "accounts" not in network_config:
|
131
186
|
raise ValueError(f"network {network_name} must have accounts")
|
187
|
+
if "chain_type" not in network_config:
|
188
|
+
raise ValueError(
|
189
|
+
f"network {network_name} must have a chain_type. Valid values: localnet, studionet, testnet_asimov"
|
190
|
+
)
|
132
191
|
|
133
192
|
|
134
193
|
def validate_raw_user_config(config: dict):
|
@@ -207,7 +266,10 @@ def _get_overridden_networks(raw_config: dict) -> tuple[dict, str]:
|
|
207
266
|
networks_config = {}
|
208
267
|
for network_name, network_config in networks.items():
|
209
268
|
if network_name in PRECONFIGURED_NETWORKS:
|
210
|
-
|
269
|
+
# Clone to avoid mutating the cached default instance
|
270
|
+
networks_config[network_name] = replace(
|
271
|
+
default_config.networks[network_name]
|
272
|
+
)
|
211
273
|
if network_config is None:
|
212
274
|
continue
|
213
275
|
|
@@ -224,19 +286,45 @@ def _get_overridden_networks(raw_config: dict) -> tuple[dict, str]:
|
|
224
286
|
networks_config[network_name].leader_only = network_config[
|
225
287
|
"leader_only"
|
226
288
|
]
|
289
|
+
if "default_wait_interval" in network_config:
|
290
|
+
networks_config[network_name].default_wait_interval = network_config[
|
291
|
+
"default_wait_interval"
|
292
|
+
]
|
293
|
+
if "default_wait_retries" in network_config:
|
294
|
+
networks_config[network_name].default_wait_retries = network_config[
|
295
|
+
"default_wait_retries"
|
296
|
+
]
|
297
|
+
if "test_with_mocks" in network_config:
|
298
|
+
networks_config[network_name].test_with_mocks = network_config[
|
299
|
+
"test_with_mocks"
|
300
|
+
]
|
301
|
+
if "chain_type" in network_config:
|
302
|
+
networks_config[network_name].chain_type = network_config["chain_type"]
|
227
303
|
continue
|
228
304
|
|
229
305
|
url = network_config["url"]
|
230
306
|
accounts = network_config["accounts"]
|
231
307
|
from_account = network_config.get("from", accounts[0])
|
232
308
|
network_id = network_config.get("id")
|
233
|
-
leader_only = network_config.get("leader_only",
|
309
|
+
leader_only = network_config.get("leader_only", DEFAULT_LEADER_ONLY)
|
310
|
+
default_wait_interval = network_config.get(
|
311
|
+
"default_wait_interval", DEFAULT_WAIT_INTERVAL
|
312
|
+
)
|
313
|
+
default_wait_retries = network_config.get(
|
314
|
+
"default_wait_retries", DEFAULT_WAIT_RETRIES
|
315
|
+
)
|
316
|
+
test_with_mocks = network_config.get("test_with_mocks", DEFAULT_TEST_WITH_MOCKS)
|
317
|
+
chain_type = network_config["chain_type"] # Required for custom networks
|
234
318
|
networks_config[network_name] = NetworkConfigData(
|
235
319
|
id=network_id,
|
236
320
|
url=url,
|
237
321
|
accounts=accounts,
|
238
322
|
from_account=from_account,
|
239
323
|
leader_only=leader_only,
|
324
|
+
default_wait_interval=default_wait_interval,
|
325
|
+
default_wait_retries=default_wait_retries,
|
326
|
+
test_with_mocks=test_with_mocks,
|
327
|
+
chain_type=chain_type,
|
240
328
|
)
|
241
329
|
return networks_config, user_default_network
|
242
330
|
|
@@ -1,79 +0,0 @@
|
|
1
|
-
genlayer_test-0.7.0.dist-info/licenses/LICENSE,sha256=che_H4vE0QUx3HvWrAa1_jDEVInift0U6VO15-QqEls,1064
|
2
|
-
gltest/__init__.py,sha256=qoBV3IgDJr8uh9262XsWNMhi-ilkSgMqKVC9FVMk7cw,372
|
3
|
-
gltest/accounts.py,sha256=HUmWguJMolggQaZNRPw-LGlRlQCjLLdUanKRowMv6pI,812
|
4
|
-
gltest/assertions.py,sha256=0dEk0VxcHK4I7GZPHxJmz-2jaA60V499gOSR74rZbfM,1748
|
5
|
-
gltest/clients.py,sha256=1dX6wmG3QCevQRLbSaFlHymZSb-sJ5aYwet1IoX2nbA,1554
|
6
|
-
gltest/exceptions.py,sha256=deJPmrTe5gF33qkkKF2IVJY7lc_knI7Ql3N7jZ8aLZs,510
|
7
|
-
gltest/fixtures.py,sha256=EJXmqcC3LD03v07mepacFl58lAdhbLj6bP5rtALYISk,2507
|
8
|
-
gltest/logging.py,sha256=jAkHsuMm-AEx1Xu1srU6W-0YzTwXJB48mCK-OVzAiN4,342
|
9
|
-
gltest/types.py,sha256=LJogYw6jQGoZnmE9Kx-YjNBRHWe3-mGsVIFP6R-zwSw,636
|
10
|
-
gltest/utils.py,sha256=-gHhjrS7i_GhDG3sKOq2qsTtYBt4HHgXHEXh-3RB_rI,573
|
11
|
-
gltest/artifacts/__init__.py,sha256=qTt3TE19gVNWnQLUlt5aDe4nNvJ2YJ1jzDkMmYIsCG0,194
|
12
|
-
gltest/artifacts/contract.py,sha256=KChpmfjZod_0dVB8y-dvWz6IVm7QlIJsgG2ArtvVDaU,6457
|
13
|
-
gltest/contracts/__init__.py,sha256=A9bvEtYOoqoHS8TLlFBfmNOnfwdsJPEf-AZuikagCHM,166
|
14
|
-
gltest/contracts/contract.py,sha256=jLF_ojSM6IIbdGO2_DhsO79r2wZ2Z8eBAJRrZk2qVTI,7748
|
15
|
-
gltest/contracts/contract_factory.py,sha256=PpWh4mKf1hDMv_yms5lwFV_EoXxXiuNfdXbwD74hbAU,8929
|
16
|
-
gltest/contracts/contract_functions.py,sha256=W6Dpw1z-n9EeJxlNtIbeVnzpv4BPABhtgmgjnS8-P0w,2573
|
17
|
-
gltest/contracts/method_stats.py,sha256=zWWjvf7K5VC4yrHpDIR717VF7LYp1RaZ1Hr_RZvWxJA,5150
|
18
|
-
gltest/contracts/stats_collector.py,sha256=iwsnoYo5aZbI4SVMH7dR-5CQgkglExXfsvaUDpwcdss,9286
|
19
|
-
gltest/contracts/utils.py,sha256=TTXgcXn9BuRIlKJrjwmU7R3l1IgXsXk2luM-r3lfbbg,296
|
20
|
-
gltest/helpers/__init__.py,sha256=I7HiTu_H7_hP65zY6Wl02r-5eAMr2eZvqBVmusuQLX4,180
|
21
|
-
gltest/helpers/fixture_snapshot.py,sha256=bMgvlEVQBGIQzj7NOyosXWlphI1H2C1o75Zo0C-kGfQ,1931
|
22
|
-
gltest/helpers/take_snapshot.py,sha256=-QkaBvFG4ZsNKv_nCSEsy5Ze1pICOHxVhReSeQmZUlY,1276
|
23
|
-
gltest_cli/logging.py,sha256=WXVhfq9vT6FtV_jxDqGEGia1ZWSIUKAfmWRnZd_gWQk,1266
|
24
|
-
gltest_cli/main.py,sha256=Ti2-0Ev1x5_cM0D1UKqdgaDt80CDHEQGtdRne2qLm4M,53
|
25
|
-
gltest_cli/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
26
|
-
gltest_cli/config/constants.py,sha256=LG74S_65OXhqweL__PGRV6Ms8UkMFYSeK7Sq88viBis,411
|
27
|
-
gltest_cli/config/general.py,sha256=ezpoGsT8grO9zQH6RugV14b1GzeFt-htYToHQBJhNvY,186
|
28
|
-
gltest_cli/config/plugin.py,sha256=TsK3JnKKz_9azASHcKKSY5ohCl5TmxVUk_YEGIc4A28,6469
|
29
|
-
gltest_cli/config/pytest_context.py,sha256=Ze8JSkrwMTCE8jIhpzU_71CEXg92SiEPvSgNTp-gbS4,243
|
30
|
-
gltest_cli/config/types.py,sha256=0x8I-Xvzul9lGkPL0GusxJPhJCNajx-ghm0N-V5P594,8206
|
31
|
-
gltest_cli/config/user.py,sha256=SXGWQnA6422vRhQ9Xwxuzts7ZARcBIJZcRFSxN56PV4,9970
|
32
|
-
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
33
|
-
tests/conftest.py,sha256=RKdoE5_zcMimeojAoA_GSFI9du4pMzMi1vZ1njtfoAs,28
|
34
|
-
tests/examples/contracts/football_prediction_market.py,sha256=9xwU8f3q73Hae-ByHy_wauhMPLRnLZd4XKNrClnjOJM,3248
|
35
|
-
tests/examples/contracts/intelligent_oracle.py,sha256=cZNGbjKMXY-pimVmPIKIlS963Gd3L1JAipq0VBR1J5Q,12360
|
36
|
-
tests/examples/contracts/intelligent_oracle_factory.py,sha256=6UApEdPzcUXR18wMpaQXtWpEKeQjU0zDkI5ezghuJUo,1526
|
37
|
-
tests/examples/contracts/invalid_deploy.py,sha256=cHXV0aq8gfbWdvjchnjSeoZDCCC-5iNdLGUkJi-tQfo,228
|
38
|
-
tests/examples/contracts/llm_erc20.py,sha256=pOvSUszCtC_f5yDX0tZnj494Ce10uESZ09JLLE8V67o,2534
|
39
|
-
tests/examples/contracts/log_indexer.py,sha256=Nlf8XUt13ujam3k6hbbVrPHK-KJ366Csz1TBjc4P07g,1901
|
40
|
-
tests/examples/contracts/multi_read_erc20.py,sha256=28qYqn191Ro3rP7YJtZwL6Sc7JDXTeh8_QoqvdVPdqM,864
|
41
|
-
tests/examples/contracts/multi_tenant_storage.py,sha256=ceq3X4E7pkvSdy7eQMhAoHme4KFedjAcpkfUYBmcgVM,1941
|
42
|
-
tests/examples/contracts/read_erc20.py,sha256=RgH269F0x482WuLLYcacBnZsGJjhgJp6sG_33cV6Z-w,454
|
43
|
-
tests/examples/contracts/simple_time_contract.py,sha256=-9p_umlzUW5X2NL6IknO6Khs_114izSWifP5D2bWCMo,2512
|
44
|
-
tests/examples/contracts/storage.py,sha256=3DD3qvzb0JkVcBtu240e5kaZWgkh-bu6YExqBUYvfaw,501
|
45
|
-
tests/examples/contracts/user_storage.py,sha256=2W2Iv-hQZMkAaPl2RY_F-OeJpD4IlPxgWzN6e1bTkKE,649
|
46
|
-
tests/examples/contracts/wizard_of_coin.py,sha256=Y8daPpoSKdM8wfbCPOIgEdpkLIA1ZMmeg6Hu5fBB-kU,1624
|
47
|
-
tests/examples/contracts/multi_file_contract/__init__.py,sha256=xDn_wS62GhCmnYoI6xIqlic2i882SoPnR2TEauKc9tQ,575
|
48
|
-
tests/examples/contracts/multi_file_contract/other.py,sha256=jHDtjUL3eAUgE6yOYKFw_RfAH7kIwk8CvxUjbWHNruk,236
|
49
|
-
tests/examples/tests/test_football_prediction_market.py,sha256=f2hfDK76WrNJZtFkTPKoPRR6bkmFLEssnlwwltSnU9A,1111
|
50
|
-
tests/examples/tests/test_intelligent_oracle_factory.py,sha256=sL26aeb84XpJPCSUSIX3yrbwQE8GZtvNcsaKTpngFmY,7611
|
51
|
-
tests/examples/tests/test_invalid_deploy.py,sha256=pppM8_Vn4DXcWq9iyJXb0SpZnKXkIyJxoIDW5ApCS94,814
|
52
|
-
tests/examples/tests/test_llm_erc20.py,sha256=zb5F_7NgvZXhvqL2nULwzuTT6LGDprSy0WgrdjY7pZc,2096
|
53
|
-
tests/examples/tests/test_llm_erc20_analyze.py,sha256=rVnC3iQW_1J3P6cczEVOOG84K6ldCzlZbMO9WXQdRds,1849
|
54
|
-
tests/examples/tests/test_log_indexer.py,sha256=46AqL7qquNc9GX2wxFxVcQXLqruMnPmxXl1yeB0-KZ4,2869
|
55
|
-
tests/examples/tests/test_multi_file_contract.py,sha256=1Emj6ze4f-OrpxvqExeJhPHjK0cNAQW54MXf6fy2Yuc,469
|
56
|
-
tests/examples/tests/test_multi_read_erc20.py,sha256=pSZUxoB33Z2EBtcvXxfUgwGSi_h7ryPoovkiNIfNAVQ,3713
|
57
|
-
tests/examples/tests/test_multi_tenant_storage.py,sha256=8B3tjnRbT8ATN5obtWkGsN3nOtBU9OSjuaH9aEat3vc,2935
|
58
|
-
tests/examples/tests/test_read_erc20.py,sha256=vLGQwguaNnT497nSq-vt4LrXj4ehn5ZSgfPt0GVFoPc,1254
|
59
|
-
tests/examples/tests/test_simple_time_contract.py,sha256=HQCJNheFyaHh73jZHyGOhNItzg045o8XsW-jLnNp-xc,3199
|
60
|
-
tests/examples/tests/test_storage.py,sha256=y46nPjM-Jd9FVJmaNE29RPqamzxVwYtPPWE_GlXUsls,774
|
61
|
-
tests/examples/tests/test_user_storage.py,sha256=wk0r0AXfKNgI7Eeyc8noNlJKvZBFXDbXTQE_u19XxBQ,2927
|
62
|
-
tests/examples/tests/test_wizard_of_coin.py,sha256=AOQTanDsfZt9zIGkqZass_4BsGcVKTHzqRejN4KhSPI,854
|
63
|
-
tests/gltest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
64
|
-
tests/gltest/artifact/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
65
|
-
tests/gltest/artifact/test_contract_definition.py,sha256=riNNZ5Bu18zn5yuKXvJ5djRDmBNsFZTT0sdw9vX4Js8,2066
|
66
|
-
tests/gltest/artifact/contracts/duplicate_ic_contract_1.py,sha256=bSWsUVjBy5cGtI72cjnkstsMzuUJbB3IG5JjTxOF-dc,500
|
67
|
-
tests/gltest/artifact/contracts/duplicate_ic_contract_2.py,sha256=bSWsUVjBy5cGtI72cjnkstsMzuUJbB3IG5JjTxOF-dc,500
|
68
|
-
tests/gltest/artifact/contracts/not_ic_contract.py,sha256=hQyGnYiiVceYdLI2WrvcFgPqzy1S4-YMb9FPhiHEGSA,510
|
69
|
-
tests/gltest/assertions/test_assertions.py,sha256=qzVrOdOM4xYtIy1sFHVAD_-naDHOequ23tEN0MELh0k,10781
|
70
|
-
tests/gltest_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
71
|
-
tests/gltest_cli/config/test_config_integration.py,sha256=vPTzr3_h9UMw7m72HogBJE2ZPhRduXoLSq18Z7FoCWQ,10105
|
72
|
-
tests/gltest_cli/config/test_general_config.py,sha256=UHtSwVnso-ZwNtYM0Z4v2sCLKwyrVbHlk6b1leVfV84,14703
|
73
|
-
tests/gltest_cli/config/test_plugin.py,sha256=COrEK5tHP1BSzanWbZHmN3EQgE9VuTcPvB95pgOvKS4,7974
|
74
|
-
tests/gltest_cli/config/test_user.py,sha256=JxR655oUFoM9quWQO68CVPKRpT0TMpzS3bF6j6NWyT4,14401
|
75
|
-
genlayer_test-0.7.0.dist-info/METADATA,sha256=o89bAkGCyeJbcOUVD1ElUDG37zLVClakUp3tvs6oKsc,32466
|
76
|
-
genlayer_test-0.7.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
77
|
-
genlayer_test-0.7.0.dist-info/entry_points.txt,sha256=RWPcSArBpz_G4BYioh5L8Q8hyClRbSgzLimjcWMp-BQ,94
|
78
|
-
genlayer_test-0.7.0.dist-info/top_level.txt,sha256=-qiGZxTRBytujzgVcKpxjvQ-WNeUDjXa59ceGMwMpko,24
|
79
|
-
genlayer_test-0.7.0.dist-info/RECORD,,
|
tests/__init__.py
DELETED
File without changes
|
tests/conftest.py
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
pytest_plugins = "pytester"
|
@@ -1,100 +0,0 @@
|
|
1
|
-
# v0.1.0
|
2
|
-
# { "Depends": "py-genlayer:latest" }
|
3
|
-
|
4
|
-
from genlayer import *
|
5
|
-
|
6
|
-
import json
|
7
|
-
import typing
|
8
|
-
|
9
|
-
|
10
|
-
class PredictionMarket(gl.Contract):
|
11
|
-
has_resolved: bool
|
12
|
-
team1: str
|
13
|
-
team2: str
|
14
|
-
resolution_url: str
|
15
|
-
winner: u256
|
16
|
-
score: str
|
17
|
-
|
18
|
-
def __init__(self, game_date: str, team1: str, team2: str):
|
19
|
-
"""
|
20
|
-
Initializes a new instance of the prediction market with the specified game date and teams.
|
21
|
-
|
22
|
-
Args:
|
23
|
-
game_date (str): The date of the game in the format 'YYYY-MM-DD'.
|
24
|
-
team1 (str): The name of the first team.
|
25
|
-
team2 (str): The name of the second team.
|
26
|
-
|
27
|
-
Attributes:
|
28
|
-
has_resolved (bool): Indicates whether the game's resolution has been processed. Default is False.
|
29
|
-
game_date (str): The date of the game.
|
30
|
-
resolution_url (str): The URL to the game's resolution on BBC Sport.
|
31
|
-
team1 (str): The name of the first team.
|
32
|
-
team2 (str): The name of the second team.
|
33
|
-
"""
|
34
|
-
self.has_resolved = False
|
35
|
-
self.resolution_url = (
|
36
|
-
"https://www.bbc.com/sport/football/scores-fixtures/" + game_date
|
37
|
-
)
|
38
|
-
self.team1 = team1
|
39
|
-
self.team2 = team2
|
40
|
-
self.winner = u256(0)
|
41
|
-
self.score = ""
|
42
|
-
|
43
|
-
@gl.public.write
|
44
|
-
def resolve(self) -> typing.Any:
|
45
|
-
|
46
|
-
if self.has_resolved:
|
47
|
-
return "Already resolved"
|
48
|
-
|
49
|
-
market_resolution_url = self.resolution_url
|
50
|
-
team1 = self.team1
|
51
|
-
team2 = self.team2
|
52
|
-
|
53
|
-
def get_match_result() -> typing.Any:
|
54
|
-
web_data = gl.nondet.web.render(market_resolution_url, mode="text")
|
55
|
-
print(web_data)
|
56
|
-
|
57
|
-
task = f"""
|
58
|
-
In the following web page, find the winning team in a matchup between the following teams:
|
59
|
-
Team 1: {team1}
|
60
|
-
Team 2: {team2}
|
61
|
-
|
62
|
-
Web page content:
|
63
|
-
{web_data}
|
64
|
-
End of web page data.
|
65
|
-
|
66
|
-
If it says "Kick off [time]" between the names of the two teams, it means the game hasn't started yet.
|
67
|
-
If you fail to extract the score, assume the game is not resolved yet.
|
68
|
-
|
69
|
-
Respond with the following JSON format:
|
70
|
-
{{
|
71
|
-
"score": str, // The score with numbers only, e.g, "1:2", or "-" if the game is not resolved yet
|
72
|
-
"winner": int, // The number of the winning team, 0 for draw, or -1 if the game is not yet finished
|
73
|
-
}}
|
74
|
-
It is mandatory that you respond only using the JSON format above,
|
75
|
-
nothing else. Don't include any other words or characters,
|
76
|
-
your output must be only JSON without any formatting prefix or suffix.
|
77
|
-
This result should be perfectly parsable by a JSON parser without errors.
|
78
|
-
"""
|
79
|
-
result = (
|
80
|
-
gl.nondet.exec_prompt(task).replace("```json", "").replace("```", "")
|
81
|
-
)
|
82
|
-
print(result)
|
83
|
-
return json.loads(result)
|
84
|
-
|
85
|
-
result_json = gl.eq_principle.strict_eq(get_match_result)
|
86
|
-
|
87
|
-
if result_json["winner"] > -1:
|
88
|
-
self.has_resolved = True
|
89
|
-
self.winner = result_json["winner"]
|
90
|
-
self.score = result_json["score"]
|
91
|
-
|
92
|
-
return result_json
|
93
|
-
|
94
|
-
@gl.public.view
|
95
|
-
def get_resolution_data(self) -> dict[str, typing.Any]:
|
96
|
-
return {
|
97
|
-
"winner": self.winner,
|
98
|
-
"score": self.score,
|
99
|
-
"has_resolved": self.has_resolved,
|
100
|
-
}
|