genlayer-test 0.1.3__py3-none-any.whl → 0.3.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.1.3.dist-info → genlayer_test-0.3.0.dist-info}/METADATA +77 -10
- genlayer_test-0.3.0.dist-info/RECORD +65 -0
- {genlayer_test-0.1.3.dist-info → genlayer_test-0.3.0.dist-info}/entry_points.txt +1 -1
- gltest/__init__.py +4 -4
- gltest/artifacts/__init__.py +5 -2
- gltest/artifacts/contract.py +94 -14
- gltest/glchain/__init__.py +3 -3
- gltest/glchain/account.py +15 -11
- gltest/glchain/client.py +39 -3
- gltest/glchain/contract.py +98 -31
- gltest/helpers/fixture_snapshot.py +3 -2
- gltest_cli/config/__init__.py +0 -0
- gltest_cli/config/constants.py +10 -0
- gltest_cli/config/general.py +10 -0
- gltest_cli/config/plugin.py +102 -0
- gltest_cli/config/types.py +137 -0
- gltest_cli/config/user.py +222 -0
- gltest_cli/logging.py +51 -0
- tests/__init__.py +0 -0
- tests/examples/tests/test_llm_erc20.py +2 -2
- tests/examples/tests/test_multi_read_erc20.py +13 -3
- tests/examples/tests/test_multi_tenant_storage.py +12 -3
- tests/examples/tests/test_read_erc20.py +2 -2
- tests/examples/tests/test_storage.py +4 -2
- tests/examples/tests/test_user_storage.py +17 -3
- tests/gltest/__init__.py +0 -0
- tests/gltest/artifact/__init__.py +0 -0
- tests/gltest/artifact/contracts/duplicate_ic_contract_1.py +22 -0
- tests/gltest/artifact/contracts/duplicate_ic_contract_2.py +22 -0
- tests/{artifact → gltest/artifact}/test_contract_definition.py +29 -30
- tests/gltest_cli/__init__.py +0 -0
- tests/gltest_cli/config/test_plugin.py +127 -0
- tests/gltest_cli/config/test_user.py +351 -0
- genlayer_test-0.1.3.dist-info/RECORD +0 -53
- gltest/plugin_config.py +0 -42
- gltest/plugin_hooks.py +0 -51
- tests/plugin/test_plugin_hooks.py +0 -78
- {genlayer_test-0.1.3.dist-info → genlayer_test-0.3.0.dist-info}/WHEEL +0 -0
- {genlayer_test-0.1.3.dist-info → genlayer_test-0.3.0.dist-info}/licenses/LICENSE +0 -0
- {genlayer_test-0.1.3.dist-info → genlayer_test-0.3.0.dist-info}/top_level.txt +0 -0
- /tests/{plugin/conftest.py → conftest.py} +0 -0
- /tests/{artifact → gltest/artifact}/contracts/not_ic_contract.py +0 -0
- /tests/{assertions → gltest/assertions}/test_assertions.py +0 -0
@@ -0,0 +1,222 @@
|
|
1
|
+
import os
|
2
|
+
import yaml
|
3
|
+
import re
|
4
|
+
from dotenv import load_dotenv
|
5
|
+
from pathlib import Path
|
6
|
+
from functools import lru_cache
|
7
|
+
from gltest.glchain.account import create_accounts
|
8
|
+
from gltest_cli.config.constants import (
|
9
|
+
GLTEST_CONFIG_FILE,
|
10
|
+
DEFAULT_NETWORK,
|
11
|
+
DEFAULT_RPC_URL,
|
12
|
+
DEFAULT_ENVIRONMENT,
|
13
|
+
DEFAULT_CONTRACTS_DIR,
|
14
|
+
DEFAULT_NETWORK_ID,
|
15
|
+
)
|
16
|
+
from gltest_cli.config.types import UserConfig, NetworkConfigData, PathConfig
|
17
|
+
|
18
|
+
VALID_ROOT_KEYS = ["networks", "paths", "environment"]
|
19
|
+
VALID_NETWORK_KEYS = ["id", "url", "accounts", "from"]
|
20
|
+
VALID_PATHS_KEYS = ["contracts"]
|
21
|
+
|
22
|
+
|
23
|
+
@lru_cache(maxsize=1)
|
24
|
+
def get_default_user_config() -> UserConfig:
|
25
|
+
accounts = create_accounts(n_accounts=10)
|
26
|
+
accounts_private_keys = [account.key.hex() for account in accounts]
|
27
|
+
|
28
|
+
return UserConfig(
|
29
|
+
networks={
|
30
|
+
DEFAULT_NETWORK: NetworkConfigData(
|
31
|
+
id=DEFAULT_NETWORK_ID,
|
32
|
+
url=DEFAULT_RPC_URL,
|
33
|
+
accounts=accounts_private_keys,
|
34
|
+
from_account=accounts_private_keys[0],
|
35
|
+
),
|
36
|
+
},
|
37
|
+
paths=PathConfig(contracts=DEFAULT_CONTRACTS_DIR),
|
38
|
+
environment=DEFAULT_ENVIRONMENT,
|
39
|
+
default_network=DEFAULT_NETWORK,
|
40
|
+
)
|
41
|
+
|
42
|
+
|
43
|
+
def resolve_env_vars(obj):
|
44
|
+
if isinstance(obj, str):
|
45
|
+
return re.sub(
|
46
|
+
r"\${(\w+)}",
|
47
|
+
lambda m: os.getenv(m.group(1), f"<UNSET:{m.group(1)}>"),
|
48
|
+
obj,
|
49
|
+
)
|
50
|
+
elif isinstance(obj, dict):
|
51
|
+
return {k: resolve_env_vars(v) for k, v in obj.items()}
|
52
|
+
elif isinstance(obj, list):
|
53
|
+
return [resolve_env_vars(i) for i in obj]
|
54
|
+
return obj
|
55
|
+
|
56
|
+
|
57
|
+
def validate_network_config(network_name: str, network_config: dict):
|
58
|
+
if not isinstance(network_config, dict):
|
59
|
+
raise ValueError(f"network {network_name} must be a dictionary")
|
60
|
+
|
61
|
+
for key in network_config:
|
62
|
+
if key not in VALID_NETWORK_KEYS:
|
63
|
+
raise ValueError(
|
64
|
+
f"Invalid network key: {key}, valid keys are: {VALID_NETWORK_KEYS}"
|
65
|
+
)
|
66
|
+
|
67
|
+
if "id" in network_config and not isinstance(network_config["id"], int):
|
68
|
+
raise ValueError(f"network {network_name} id must be an integer")
|
69
|
+
|
70
|
+
if "url" in network_config and not isinstance(network_config["url"], str):
|
71
|
+
raise ValueError(f"network {network_name} url must be a string")
|
72
|
+
|
73
|
+
if "accounts" in network_config and not isinstance(
|
74
|
+
network_config["accounts"], list
|
75
|
+
):
|
76
|
+
raise ValueError(f"network {network_name} accounts must be a list")
|
77
|
+
if "accounts" in network_config and not all(
|
78
|
+
isinstance(acc, str) for acc in network_config["accounts"]
|
79
|
+
):
|
80
|
+
raise ValueError(f"network {network_name} accounts must be strings")
|
81
|
+
|
82
|
+
if "from" in network_config and not isinstance(network_config["from"], str):
|
83
|
+
raise ValueError(f"network {network_name} from must be a string")
|
84
|
+
|
85
|
+
# For non-default networks, url and accounts are required
|
86
|
+
if network_name != DEFAULT_NETWORK:
|
87
|
+
if "id" not in network_config:
|
88
|
+
raise ValueError(f"network {network_name} must have an id")
|
89
|
+
if "url" not in network_config:
|
90
|
+
raise ValueError(f"network {network_name} must have a url")
|
91
|
+
if "accounts" not in network_config:
|
92
|
+
raise ValueError(f"network {network_name} must have accounts")
|
93
|
+
|
94
|
+
|
95
|
+
def validate_raw_user_config(config: dict):
|
96
|
+
# Validate root keys
|
97
|
+
if not all(key in VALID_ROOT_KEYS for key in config):
|
98
|
+
raise ValueError(
|
99
|
+
f"Invalid configuration keys. Valid keys are: {VALID_ROOT_KEYS}"
|
100
|
+
)
|
101
|
+
|
102
|
+
# Validate networks
|
103
|
+
if "networks" in config:
|
104
|
+
networks = config["networks"]
|
105
|
+
if not isinstance(networks, dict):
|
106
|
+
raise ValueError("networks must be a dictionary")
|
107
|
+
|
108
|
+
default_network = networks.get("default", DEFAULT_NETWORK)
|
109
|
+
if default_network != DEFAULT_NETWORK and default_network not in networks:
|
110
|
+
raise ValueError(f"default network {default_network} not found in networks")
|
111
|
+
|
112
|
+
for name, network_config in networks.items():
|
113
|
+
if name == "default" or (
|
114
|
+
name == DEFAULT_NETWORK and network_config is None
|
115
|
+
):
|
116
|
+
continue
|
117
|
+
validate_network_config(name, network_config)
|
118
|
+
|
119
|
+
# Validate paths
|
120
|
+
if "paths" in config:
|
121
|
+
if not isinstance(config["paths"], dict):
|
122
|
+
raise ValueError("paths must be a dictionary")
|
123
|
+
if not all(key in VALID_PATHS_KEYS for key in config["paths"]):
|
124
|
+
raise ValueError(f"Invalid path keys. Valid keys are: {VALID_PATHS_KEYS}")
|
125
|
+
|
126
|
+
# Validate environment
|
127
|
+
if "environment" in config and not isinstance(config["environment"], str):
|
128
|
+
raise ValueError("environment must be a string")
|
129
|
+
|
130
|
+
|
131
|
+
def load_user_config(path: str) -> UserConfig:
|
132
|
+
with open(path, "r") as f:
|
133
|
+
raw_config = yaml.safe_load(f) or {}
|
134
|
+
|
135
|
+
validate_raw_user_config(raw_config)
|
136
|
+
load_dotenv(
|
137
|
+
dotenv_path=raw_config.get("environment", DEFAULT_ENVIRONMENT), override=True
|
138
|
+
)
|
139
|
+
resolved_config = resolve_env_vars(raw_config)
|
140
|
+
user_config = transform_raw_to_user_config_with_defaults(resolved_config)
|
141
|
+
return user_config
|
142
|
+
|
143
|
+
|
144
|
+
def transform_raw_to_user_config_with_defaults(raw_config: dict) -> UserConfig:
|
145
|
+
networks_config, user_default_network = _get_overridden_networks(raw_config)
|
146
|
+
return UserConfig(
|
147
|
+
networks=networks_config,
|
148
|
+
paths=_get_overridden_paths(raw_config),
|
149
|
+
environment=_get_overridden_environment(raw_config),
|
150
|
+
default_network=user_default_network,
|
151
|
+
)
|
152
|
+
|
153
|
+
|
154
|
+
def _get_overridden_networks(raw_config: dict) -> tuple[dict, str]:
|
155
|
+
default_config = get_default_user_config()
|
156
|
+
if "networks" not in raw_config:
|
157
|
+
return default_config.networks, default_config.default_network
|
158
|
+
|
159
|
+
networks = dict(raw_config["networks"])
|
160
|
+
user_default_network = networks.pop("default")
|
161
|
+
if user_default_network is None and DEFAULT_NETWORK in set(networks.keys()):
|
162
|
+
user_default_network = DEFAULT_NETWORK
|
163
|
+
|
164
|
+
if user_default_network is None:
|
165
|
+
raise ValueError(
|
166
|
+
"'networks.default' is required in config since you don't have 'localnet' network in 'networks'"
|
167
|
+
)
|
168
|
+
|
169
|
+
networks_config = {}
|
170
|
+
for network_name, network_config in networks.items():
|
171
|
+
if network_name == DEFAULT_NETWORK:
|
172
|
+
networks_config[network_name] = default_config.networks[DEFAULT_NETWORK]
|
173
|
+
if network_config is None:
|
174
|
+
continue
|
175
|
+
|
176
|
+
if "url" in network_config:
|
177
|
+
networks_config[network_name].url = network_config["url"]
|
178
|
+
if "accounts" in network_config:
|
179
|
+
networks_config[network_name].accounts = network_config["accounts"]
|
180
|
+
networks_config[network_name].from_account = network_config["accounts"][
|
181
|
+
0
|
182
|
+
]
|
183
|
+
if "from" in network_config:
|
184
|
+
networks_config[network_name].from_account = network_config["from"]
|
185
|
+
continue
|
186
|
+
|
187
|
+
url = network_config["url"]
|
188
|
+
accounts = network_config["accounts"]
|
189
|
+
from_account = network_config.get("from", accounts[0])
|
190
|
+
network_id = network_config.get("id")
|
191
|
+
|
192
|
+
networks_config[network_name] = NetworkConfigData(
|
193
|
+
id=network_id,
|
194
|
+
url=url,
|
195
|
+
accounts=accounts,
|
196
|
+
from_account=from_account,
|
197
|
+
)
|
198
|
+
return networks_config, user_default_network
|
199
|
+
|
200
|
+
|
201
|
+
def _get_overridden_environment(raw_config: dict) -> str:
|
202
|
+
default_config = get_default_user_config()
|
203
|
+
if "environment" in raw_config:
|
204
|
+
return raw_config["environment"]
|
205
|
+
return default_config.environment
|
206
|
+
|
207
|
+
|
208
|
+
def _get_overridden_paths(raw_config: dict) -> PathConfig:
|
209
|
+
default_config = get_default_user_config()
|
210
|
+
if "paths" in raw_config:
|
211
|
+
return PathConfig(
|
212
|
+
contracts=Path(
|
213
|
+
raw_config.get("paths", {}).get("contracts", DEFAULT_CONTRACTS_DIR)
|
214
|
+
)
|
215
|
+
)
|
216
|
+
return default_config.paths
|
217
|
+
|
218
|
+
|
219
|
+
def user_config_exists() -> bool:
|
220
|
+
return any(
|
221
|
+
p.name == GLTEST_CONFIG_FILE for p in Path.cwd().iterdir() if p.is_file()
|
222
|
+
)
|
gltest_cli/logging.py
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
import logging
|
2
|
+
from colorama import Fore, Style, init
|
3
|
+
|
4
|
+
|
5
|
+
init()
|
6
|
+
|
7
|
+
|
8
|
+
class ColoredFormatter(logging.Formatter):
|
9
|
+
"""Custom formatter that adds colors to the log levels"""
|
10
|
+
|
11
|
+
COLORS = {
|
12
|
+
"DEBUG": Fore.BLUE,
|
13
|
+
"INFO": Fore.GREEN,
|
14
|
+
"WARNING": Fore.YELLOW,
|
15
|
+
"ERROR": Fore.RED,
|
16
|
+
"CRITICAL": Fore.RED + Style.BRIGHT,
|
17
|
+
}
|
18
|
+
|
19
|
+
def format(self, record):
|
20
|
+
levelname_plain = record.levelname
|
21
|
+
if levelname_plain in self.COLORS:
|
22
|
+
colored = (
|
23
|
+
f"{self.COLORS[levelname_plain]}{levelname_plain}{Style.RESET_ALL}"
|
24
|
+
)
|
25
|
+
record.levelname = colored
|
26
|
+
formatted = super().format(record)
|
27
|
+
record.levelname = levelname_plain
|
28
|
+
return formatted
|
29
|
+
return super().format(record)
|
30
|
+
|
31
|
+
|
32
|
+
def setup_logger():
|
33
|
+
logger = logging.getLogger("gltest")
|
34
|
+
logger.setLevel(logging.DEBUG)
|
35
|
+
|
36
|
+
if logger.handlers:
|
37
|
+
return logger
|
38
|
+
|
39
|
+
console_handler = logging.StreamHandler()
|
40
|
+
console_handler.setLevel(logging.DEBUG)
|
41
|
+
|
42
|
+
formatter = ColoredFormatter("%(levelname)s: %(message)s")
|
43
|
+
console_handler.setFormatter(formatter)
|
44
|
+
|
45
|
+
logger.addHandler(console_handler)
|
46
|
+
return logger
|
47
|
+
|
48
|
+
|
49
|
+
logger = setup_logger()
|
50
|
+
|
51
|
+
__all__ = ["logger"]
|
tests/__init__.py
ADDED
File without changes
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from gltest import get_contract_factory,
|
1
|
+
from gltest import get_contract_factory, get_default_account, create_account
|
2
2
|
from gltest.assertions import tx_execution_succeeded
|
3
3
|
|
4
4
|
TOKEN_TOTAL_SUPPLY = 1000
|
@@ -7,7 +7,7 @@ TRANSFER_AMOUNT = 100
|
|
7
7
|
|
8
8
|
def test_llm_erc20():
|
9
9
|
# Account Setup
|
10
|
-
from_account_a =
|
10
|
+
from_account_a = get_default_account()
|
11
11
|
from_account_b = create_account()
|
12
12
|
|
13
13
|
# Deploy Contract
|
@@ -1,5 +1,7 @@
|
|
1
|
-
from gltest import get_contract_factory, create_account
|
1
|
+
from gltest import get_contract_factory, create_account, get_accounts
|
2
2
|
from gltest.assertions import tx_execution_succeeded
|
3
|
+
from gltest_cli.config.general import get_general_config
|
4
|
+
from genlayer_py.chains import testnet_asimov
|
3
5
|
|
4
6
|
|
5
7
|
def test_multi_read_erc20():
|
@@ -15,9 +17,17 @@ def test_multi_read_erc20():
|
|
15
17
|
|
16
18
|
This test demonstrates the integration contract to contract reads
|
17
19
|
"""
|
20
|
+
general_config = get_general_config()
|
21
|
+
chain = general_config.get_chain()
|
22
|
+
|
18
23
|
TOKEN_TOTAL_SUPPLY = 1000
|
19
|
-
|
20
|
-
|
24
|
+
|
25
|
+
if chain.id == testnet_asimov.id:
|
26
|
+
from_account_doge = get_accounts()[0]
|
27
|
+
from_account_shiba = get_accounts()[1]
|
28
|
+
else:
|
29
|
+
from_account_doge = create_account()
|
30
|
+
from_account_shiba = create_account()
|
21
31
|
|
22
32
|
# LLM ERC20
|
23
33
|
llm_erc20_factory = get_contract_factory("LlmErc20")
|
@@ -1,5 +1,7 @@
|
|
1
|
-
from gltest import get_contract_factory, create_account
|
1
|
+
from gltest import get_contract_factory, create_account, get_accounts
|
2
2
|
from gltest.assertions import tx_execution_succeeded
|
3
|
+
from gltest_cli.config.general import get_general_config
|
4
|
+
from genlayer_py.chains import testnet_asimov
|
3
5
|
|
4
6
|
|
5
7
|
def test_multi_tenant_storage():
|
@@ -15,8 +17,15 @@ def test_multi_tenant_storage():
|
|
15
17
|
|
16
18
|
This test demonstrates contract-to-contract interactions and multi-tenant data management.
|
17
19
|
"""
|
18
|
-
|
19
|
-
|
20
|
+
general_config = get_general_config()
|
21
|
+
chain = general_config.get_chain()
|
22
|
+
|
23
|
+
if chain.id == testnet_asimov.id:
|
24
|
+
user_account_a = get_accounts()[0]
|
25
|
+
user_account_b = get_accounts()[1]
|
26
|
+
else:
|
27
|
+
user_account_a = create_account()
|
28
|
+
user_account_b = create_account()
|
20
29
|
|
21
30
|
# Storage Contracts
|
22
31
|
storage_factory = get_contract_factory("Storage")
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from gltest import get_contract_factory,
|
1
|
+
from gltest import get_contract_factory, get_default_account
|
2
2
|
|
3
3
|
|
4
4
|
def test_read_erc20():
|
@@ -32,6 +32,6 @@ def test_read_erc20():
|
|
32
32
|
|
33
33
|
# check balance
|
34
34
|
contract_state = read_erc20_contract.get_balance_of(
|
35
|
-
args=[
|
35
|
+
args=[get_default_account().address]
|
36
36
|
)
|
37
37
|
assert contract_state == TOKEN_TOTAL_SUPPLY
|
@@ -8,14 +8,16 @@ UPDATED_STATE = "b"
|
|
8
8
|
|
9
9
|
def test_storage():
|
10
10
|
factory = get_contract_factory("Storage")
|
11
|
-
contract = factory.deploy(args=[INITIAL_STATE])
|
11
|
+
contract = factory.deploy(args=[INITIAL_STATE], wait_retries=40)
|
12
12
|
|
13
13
|
# Get initial state
|
14
14
|
contract_state_1 = contract.get_storage(args=[])
|
15
15
|
assert contract_state_1 == INITIAL_STATE
|
16
16
|
|
17
17
|
# Update State
|
18
|
-
transaction_response_call_1 = contract.update_storage(
|
18
|
+
transaction_response_call_1 = contract.update_storage(
|
19
|
+
args=[UPDATED_STATE], wait_retries=40
|
20
|
+
)
|
19
21
|
assert tx_execution_succeeded(transaction_response_call_1)
|
20
22
|
|
21
23
|
# Get Updated State
|
@@ -1,5 +1,12 @@
|
|
1
|
-
from gltest import
|
1
|
+
from gltest import (
|
2
|
+
get_contract_factory,
|
3
|
+
get_default_account,
|
4
|
+
create_account,
|
5
|
+
get_accounts,
|
6
|
+
)
|
2
7
|
from gltest.assertions import tx_execution_succeeded
|
8
|
+
from gltest_cli.config.general import get_general_config
|
9
|
+
from genlayer_py.chains import testnet_asimov
|
3
10
|
|
4
11
|
|
5
12
|
INITIAL_STATE_USER_A = "user_a_initial_state"
|
@@ -9,9 +16,16 @@ UPDATED_STATE_USER_B = "user_b_updated_state"
|
|
9
16
|
|
10
17
|
|
11
18
|
def test_user_storage():
|
19
|
+
general_config = get_general_config()
|
20
|
+
chain = general_config.get_chain()
|
21
|
+
|
12
22
|
# Account Setup
|
13
|
-
|
14
|
-
|
23
|
+
if chain.id == testnet_asimov.id:
|
24
|
+
from_account_a = get_accounts()[0]
|
25
|
+
from_account_b = get_accounts()[1]
|
26
|
+
else:
|
27
|
+
from_account_a = get_default_account()
|
28
|
+
from_account_b = create_account()
|
15
29
|
|
16
30
|
factory = get_contract_factory("UserStorage")
|
17
31
|
contract = factory.deploy()
|
tests/gltest/__init__.py
ADDED
File without changes
|
File without changes
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# { "Depends": "py-genlayer:test" }
|
2
|
+
|
3
|
+
from genlayer import *
|
4
|
+
|
5
|
+
|
6
|
+
# contract class
|
7
|
+
class DuplicateContract(gl.Contract):
|
8
|
+
storage: str
|
9
|
+
|
10
|
+
# constructor
|
11
|
+
def __init__(self, initial_storage: str):
|
12
|
+
self.storage = initial_storage
|
13
|
+
|
14
|
+
# read methods must be annotated with view
|
15
|
+
@gl.public.view
|
16
|
+
def get_storage(self) -> str:
|
17
|
+
return self.storage
|
18
|
+
|
19
|
+
# write method
|
20
|
+
@gl.public.write
|
21
|
+
def update_storage(self, new_storage: str) -> None:
|
22
|
+
self.storage = new_storage
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# { "Depends": "py-genlayer:test" }
|
2
|
+
|
3
|
+
from genlayer import *
|
4
|
+
|
5
|
+
|
6
|
+
# contract class
|
7
|
+
class DuplicateContract(gl.Contract):
|
8
|
+
storage: str
|
9
|
+
|
10
|
+
# constructor
|
11
|
+
def __init__(self, initial_storage: str):
|
12
|
+
self.storage = initial_storage
|
13
|
+
|
14
|
+
# read methods must be annotated with view
|
15
|
+
@gl.public.view
|
16
|
+
def get_storage(self) -> str:
|
17
|
+
return self.storage
|
18
|
+
|
19
|
+
# write method
|
20
|
+
@gl.public.write
|
21
|
+
def update_storage(self, new_storage: str) -> None:
|
22
|
+
self.storage = new_storage
|
@@ -1,43 +1,44 @@
|
|
1
1
|
import pytest
|
2
2
|
from gltest.artifacts.contract import (
|
3
|
-
|
3
|
+
find_contract_definition_from_name,
|
4
4
|
compute_contract_code,
|
5
5
|
)
|
6
|
-
from
|
6
|
+
from gltest_cli.config.general import get_general_config
|
7
7
|
from pathlib import Path
|
8
8
|
|
9
|
+
CONTRACTS_DIR = Path("tests/examples/contracts")
|
10
|
+
|
9
11
|
|
10
12
|
def test_single_file():
|
11
|
-
|
12
|
-
|
13
|
+
general_config = get_general_config()
|
14
|
+
general_config.set_contracts_dir(Path("."))
|
15
|
+
contract_definition = find_contract_definition_from_name("PredictionMarket")
|
13
16
|
|
14
17
|
assert contract_definition.contract_name == "PredictionMarket"
|
15
18
|
|
16
19
|
# Assert complete contract definition
|
17
|
-
expected_main_file_path =
|
20
|
+
expected_main_file_path = CONTRACTS_DIR / "football_prediction_market.py"
|
18
21
|
expected_runner_file_path = None
|
19
22
|
contract_code = compute_contract_code(
|
20
23
|
expected_main_file_path, expected_runner_file_path
|
21
24
|
)
|
22
25
|
assert contract_definition.contract_code == contract_code
|
23
|
-
assert (
|
24
|
-
|
25
|
-
== "examples/contracts/football_prediction_market.py"
|
26
|
+
assert str(contract_definition.main_file_path) == str(
|
27
|
+
CONTRACTS_DIR / "football_prediction_market.py"
|
26
28
|
)
|
27
29
|
assert contract_definition.runner_file_path is None
|
28
30
|
|
29
31
|
|
30
32
|
def test_multiple_files():
|
31
|
-
|
32
|
-
|
33
|
+
general_config = get_general_config()
|
34
|
+
general_config.set_contracts_dir(Path("."))
|
35
|
+
contract_definition = find_contract_definition_from_name("MultiFileContract")
|
33
36
|
|
34
37
|
assert contract_definition.contract_name == "MultiFileContract"
|
35
38
|
|
36
39
|
# Assert complete contract definition
|
37
|
-
expected_main_file_path =
|
38
|
-
expected_runner_file_path =
|
39
|
-
"examples/contracts/multi_file_contract/runner.json"
|
40
|
-
)
|
40
|
+
expected_main_file_path = CONTRACTS_DIR / "multi_file_contract/__init__.py"
|
41
|
+
expected_runner_file_path = CONTRACTS_DIR / "multi_file_contract/runner.json"
|
41
42
|
assert contract_definition.main_file_path == expected_main_file_path
|
42
43
|
assert contract_definition.runner_file_path == expected_runner_file_path
|
43
44
|
contract_code = compute_contract_code(
|
@@ -47,36 +48,33 @@ def test_multiple_files():
|
|
47
48
|
|
48
49
|
|
49
50
|
def test_single_file_legacy():
|
50
|
-
|
51
|
-
|
51
|
+
general_config = get_general_config()
|
52
|
+
general_config.set_contracts_dir(Path("."))
|
53
|
+
contract_definition = find_contract_definition_from_name("StorageLegacy")
|
52
54
|
|
53
55
|
# Assert complete contract definition
|
54
56
|
assert contract_definition.contract_name == "StorageLegacy"
|
55
|
-
expected_main_file_path =
|
57
|
+
expected_main_file_path = CONTRACTS_DIR / "storage_legacy.gpy"
|
56
58
|
expected_runner_file_path = None
|
57
59
|
contract_code = compute_contract_code(
|
58
60
|
expected_main_file_path, expected_runner_file_path
|
59
61
|
)
|
60
62
|
assert contract_definition.contract_code == contract_code
|
61
|
-
assert (
|
62
|
-
|
63
|
-
== "examples/contracts/storage_legacy.gpy"
|
63
|
+
assert str(contract_definition.main_file_path) == str(
|
64
|
+
CONTRACTS_DIR / "storage_legacy.gpy"
|
64
65
|
)
|
65
66
|
assert contract_definition.runner_file_path is None
|
66
67
|
|
67
68
|
|
68
69
|
def test_multiple_files_legacy():
|
69
|
-
|
70
|
-
|
70
|
+
general_config = get_general_config()
|
71
|
+
general_config.set_contracts_dir(Path("."))
|
72
|
+
contract_definition = find_contract_definition_from_name("MultiFileContractLegacy")
|
71
73
|
|
72
74
|
# Assert complete contract definition
|
73
75
|
assert contract_definition.contract_name == "MultiFileContractLegacy"
|
74
|
-
expected_main_file_path =
|
75
|
-
|
76
|
-
)
|
77
|
-
expected_runner_file_path = Path(
|
78
|
-
"examples/contracts/multi_file_contract_legacy/runner.json"
|
79
|
-
)
|
76
|
+
expected_main_file_path = CONTRACTS_DIR / "multi_file_contract_legacy/__init__.gpy"
|
77
|
+
expected_runner_file_path = CONTRACTS_DIR / "multi_file_contract_legacy/runner.json"
|
80
78
|
assert contract_definition.main_file_path == expected_main_file_path
|
81
79
|
assert contract_definition.runner_file_path == expected_runner_file_path
|
82
80
|
contract_code = compute_contract_code(
|
@@ -86,7 +84,8 @@ def test_multiple_files_legacy():
|
|
86
84
|
|
87
85
|
|
88
86
|
def test_class_is_not_intelligent_contract():
|
89
|
-
|
87
|
+
general_config = get_general_config()
|
88
|
+
general_config.set_contracts_dir(Path("."))
|
90
89
|
|
91
90
|
with pytest.raises(FileNotFoundError):
|
92
|
-
_ =
|
91
|
+
_ = find_contract_definition_from_name("NotICContract")
|
File without changes
|