genlayer-test 0.8.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.8.0.dist-info → genlayer_test-0.9.0.dist-info}/METADATA +29 -2
- genlayer_test-0.9.0.dist-info/RECORD +38 -0
- {genlayer_test-0.8.0.dist-info → genlayer_test-0.9.0.dist-info}/top_level.txt +0 -1
- 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.8.0.dist-info/RECORD +0 -82
- 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_custom_validators.py +0 -65
- 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.8.0.dist-info → genlayer_test-0.9.0.dist-info}/WHEEL +0 -0
- {genlayer_test-0.8.0.dist-info → genlayer_test-0.9.0.dist-info}/entry_points.txt +0 -0
- {genlayer_test-0.8.0.dist-info → genlayer_test-0.9.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,411 +0,0 @@
|
|
1
|
-
import pytest
|
2
|
-
import yaml
|
3
|
-
from unittest.mock import patch, mock_open
|
4
|
-
from gltest_cli.config.user import (
|
5
|
-
get_default_user_config,
|
6
|
-
load_user_config,
|
7
|
-
validate_raw_user_config,
|
8
|
-
transform_raw_to_user_config_with_defaults,
|
9
|
-
user_config_exists,
|
10
|
-
VALID_ROOT_KEYS,
|
11
|
-
DEFAULT_NETWORK,
|
12
|
-
DEFAULT_ENVIRONMENT,
|
13
|
-
DEFAULT_CONTRACTS_DIR,
|
14
|
-
DEFAULT_ARTIFACTS_DIR,
|
15
|
-
)
|
16
|
-
from gltest_cli.config.constants import DEFAULT_RPC_URL
|
17
|
-
from gltest_cli.config.types import UserConfig, NetworkConfigData, PathConfig
|
18
|
-
from unittest.mock import MagicMock
|
19
|
-
from pathlib import Path
|
20
|
-
|
21
|
-
# Test data
|
22
|
-
VALID_CONFIG = {
|
23
|
-
"networks": {
|
24
|
-
"default": "localnet",
|
25
|
-
"localnet": {
|
26
|
-
"url": "http://localhost:8545",
|
27
|
-
"accounts": ["0x123", "0x456"],
|
28
|
-
"from": "0x123",
|
29
|
-
},
|
30
|
-
"testnet_asimov": {
|
31
|
-
"id": 4221,
|
32
|
-
"url": "http://34.32.169.58:9151",
|
33
|
-
"accounts": ["0x123", "0x456"],
|
34
|
-
"from": "0x123",
|
35
|
-
},
|
36
|
-
},
|
37
|
-
"paths": {"contracts": "contracts", "artifacts": "artifacts"},
|
38
|
-
"environment": ".env",
|
39
|
-
}
|
40
|
-
|
41
|
-
INVALID_CONFIG = {
|
42
|
-
"networks": {
|
43
|
-
"default": "invalid_network",
|
44
|
-
"localnet": {
|
45
|
-
"url": 123, # Invalid type
|
46
|
-
"accounts": "not_a_list", # Invalid type
|
47
|
-
"from": 456, # Invalid type
|
48
|
-
},
|
49
|
-
},
|
50
|
-
"paths": {"invalid_path": "value"},
|
51
|
-
"environment": 123, # Invalid type
|
52
|
-
}
|
53
|
-
|
54
|
-
|
55
|
-
def test_get_default_user_config():
|
56
|
-
config = get_default_user_config()
|
57
|
-
|
58
|
-
# Check root structure
|
59
|
-
assert isinstance(config, UserConfig)
|
60
|
-
assert all(key in config.__dict__ for key in VALID_ROOT_KEYS)
|
61
|
-
|
62
|
-
# Check networks
|
63
|
-
assert DEFAULT_NETWORK == config.default_network
|
64
|
-
assert DEFAULT_NETWORK in config.networks
|
65
|
-
|
66
|
-
# Check network configuration
|
67
|
-
network = config.networks[DEFAULT_NETWORK]
|
68
|
-
assert isinstance(network, NetworkConfigData)
|
69
|
-
assert network.url == DEFAULT_RPC_URL
|
70
|
-
assert isinstance(network.accounts, list)
|
71
|
-
assert isinstance(network.from_account, str)
|
72
|
-
assert network.from_account in network.accounts
|
73
|
-
|
74
|
-
# Check paths
|
75
|
-
assert isinstance(config.paths, PathConfig)
|
76
|
-
assert config.paths.contracts == DEFAULT_CONTRACTS_DIR
|
77
|
-
assert config.paths.artifacts == DEFAULT_ARTIFACTS_DIR
|
78
|
-
|
79
|
-
# Check environment
|
80
|
-
assert config.environment == DEFAULT_ENVIRONMENT
|
81
|
-
|
82
|
-
|
83
|
-
def test_validate_raw_user_config_valid():
|
84
|
-
# Should not raise any exceptions
|
85
|
-
validate_raw_user_config(VALID_CONFIG)
|
86
|
-
|
87
|
-
|
88
|
-
def test_validate_raw_user_config_invalid():
|
89
|
-
with pytest.raises(ValueError, match="Invalid configuration keys"):
|
90
|
-
validate_raw_user_config({"invalid_key": "value"})
|
91
|
-
|
92
|
-
with pytest.raises(ValueError, match="networks must be a dictionary"):
|
93
|
-
validate_raw_user_config({"networks": "not_a_dict"})
|
94
|
-
|
95
|
-
with pytest.raises(ValueError, match="default network invalid_network not found"):
|
96
|
-
validate_raw_user_config(
|
97
|
-
{
|
98
|
-
"networks": {
|
99
|
-
"default": "invalid_network",
|
100
|
-
"localnet": {"url": "http://localhost:8545"},
|
101
|
-
}
|
102
|
-
}
|
103
|
-
)
|
104
|
-
|
105
|
-
with pytest.raises(ValueError, match="network localnet must be a dictionary"):
|
106
|
-
validate_raw_user_config(
|
107
|
-
{"networks": {"default": "localnet", "localnet": "not_a_dict"}}
|
108
|
-
)
|
109
|
-
|
110
|
-
with pytest.raises(ValueError, match="Invalid network key"):
|
111
|
-
validate_raw_user_config(
|
112
|
-
{"networks": {"default": "localnet", "localnet": {"invalid_key": "value"}}}
|
113
|
-
)
|
114
|
-
|
115
|
-
with pytest.raises(ValueError, match="url must be a string"):
|
116
|
-
validate_raw_user_config(
|
117
|
-
{"networks": {"default": "localnet", "localnet": {"url": 123}}}
|
118
|
-
)
|
119
|
-
|
120
|
-
with pytest.raises(ValueError, match="accounts must be a list"):
|
121
|
-
validate_raw_user_config(
|
122
|
-
{
|
123
|
-
"networks": {
|
124
|
-
"default": "localnet",
|
125
|
-
"localnet": {"accounts": "not_a_list"},
|
126
|
-
}
|
127
|
-
}
|
128
|
-
)
|
129
|
-
|
130
|
-
with pytest.raises(ValueError, match="accounts must be strings"):
|
131
|
-
validate_raw_user_config(
|
132
|
-
{"networks": {"default": "localnet", "localnet": {"accounts": [123]}}}
|
133
|
-
)
|
134
|
-
|
135
|
-
with pytest.raises(ValueError, match="from must be a string"):
|
136
|
-
validate_raw_user_config(
|
137
|
-
{"networks": {"default": "localnet", "localnet": {"from": 123}}}
|
138
|
-
)
|
139
|
-
|
140
|
-
with pytest.raises(ValueError, match="leader_only must be a boolean"):
|
141
|
-
validate_raw_user_config(
|
142
|
-
{"networks": {"default": "localnet", "localnet": {"leader_only": "true"}}}
|
143
|
-
)
|
144
|
-
|
145
|
-
with pytest.raises(ValueError, match="paths must be a dictionary"):
|
146
|
-
validate_raw_user_config({"paths": "not_a_dict"})
|
147
|
-
|
148
|
-
with pytest.raises(ValueError, match="Invalid path keys"):
|
149
|
-
validate_raw_user_config({"paths": {"invalid_path": "value"}})
|
150
|
-
|
151
|
-
with pytest.raises(ValueError, match="environment must be a string"):
|
152
|
-
validate_raw_user_config({"environment": 123})
|
153
|
-
|
154
|
-
# Test validation for non-default networks
|
155
|
-
with pytest.raises(ValueError, match="network testnet must be a dictionary"):
|
156
|
-
validate_raw_user_config(
|
157
|
-
{"networks": {"default": "localnet", "testnet": "not_a_dict"}}
|
158
|
-
)
|
159
|
-
|
160
|
-
with pytest.raises(ValueError, match="Invalid network key"):
|
161
|
-
validate_raw_user_config(
|
162
|
-
{"networks": {"default": "localnet", "testnet": {"invalid_key": "value"}}}
|
163
|
-
)
|
164
|
-
|
165
|
-
with pytest.raises(ValueError, match="url must be a string"):
|
166
|
-
validate_raw_user_config(
|
167
|
-
{"networks": {"default": "localnet", "testnet": {"url": 123}}}
|
168
|
-
)
|
169
|
-
|
170
|
-
with pytest.raises(ValueError, match="accounts must be a list"):
|
171
|
-
validate_raw_user_config(
|
172
|
-
{
|
173
|
-
"networks": {
|
174
|
-
"default": "localnet",
|
175
|
-
"testnet": {"accounts": "not_a_list"},
|
176
|
-
}
|
177
|
-
}
|
178
|
-
)
|
179
|
-
|
180
|
-
with pytest.raises(ValueError, match="accounts must be strings"):
|
181
|
-
validate_raw_user_config(
|
182
|
-
{"networks": {"default": "localnet", "testnet": {"accounts": [123]}}}
|
183
|
-
)
|
184
|
-
|
185
|
-
with pytest.raises(ValueError, match="from must be a string"):
|
186
|
-
validate_raw_user_config(
|
187
|
-
{"networks": {"default": "localnet", "testnet": {"from": 123}}}
|
188
|
-
)
|
189
|
-
|
190
|
-
with pytest.raises(ValueError, match="leader_only must be a boolean"):
|
191
|
-
validate_raw_user_config(
|
192
|
-
{"networks": {"default": "localnet", "testnet": {"leader_only": "true"}}}
|
193
|
-
)
|
194
|
-
|
195
|
-
# Test required fields for non-default networks
|
196
|
-
with pytest.raises(ValueError, match="network testnet must have an id"):
|
197
|
-
validate_raw_user_config(
|
198
|
-
{"networks": {"default": "localnet", "testnet": {"accounts": ["0x123"]}}}
|
199
|
-
)
|
200
|
-
|
201
|
-
with pytest.raises(ValueError, match="network testnet must have a url"):
|
202
|
-
validate_raw_user_config(
|
203
|
-
{
|
204
|
-
"networks": {
|
205
|
-
"default": "localnet",
|
206
|
-
"testnet": {"id": 4221, "accounts": ["0x123"]},
|
207
|
-
}
|
208
|
-
}
|
209
|
-
)
|
210
|
-
|
211
|
-
with pytest.raises(ValueError, match="network testnet must have accounts"):
|
212
|
-
validate_raw_user_config(
|
213
|
-
{
|
214
|
-
"networks": {
|
215
|
-
"default": "localnet",
|
216
|
-
"testnet": {"id": 4221, "url": "http://testnet:8545"},
|
217
|
-
}
|
218
|
-
}
|
219
|
-
)
|
220
|
-
|
221
|
-
# Test that 'from' is optional for non-default networks
|
222
|
-
valid_config_without_from = {
|
223
|
-
"networks": {
|
224
|
-
"default": "localnet",
|
225
|
-
"testnet": {
|
226
|
-
"id": 4221,
|
227
|
-
"url": "http://testnet:8545",
|
228
|
-
"accounts": ["0x123", "0x456"],
|
229
|
-
},
|
230
|
-
}
|
231
|
-
}
|
232
|
-
# Should not raise any exception
|
233
|
-
validate_raw_user_config(valid_config_without_from)
|
234
|
-
|
235
|
-
|
236
|
-
@patch("builtins.open", new_callable=mock_open, read_data=yaml.dump(VALID_CONFIG))
|
237
|
-
@patch("gltest_cli.config.user.load_dotenv")
|
238
|
-
def test_load_user_config(mock_load_dotenv, mock_file):
|
239
|
-
config = load_user_config("dummy_path")
|
240
|
-
|
241
|
-
# Check if file was opened
|
242
|
-
mock_file.assert_called_once_with("dummy_path", "r")
|
243
|
-
|
244
|
-
# Check if environment was loaded
|
245
|
-
mock_load_dotenv.assert_called_once_with(
|
246
|
-
dotenv_path=DEFAULT_ENVIRONMENT, override=True
|
247
|
-
)
|
248
|
-
|
249
|
-
# Check config structure
|
250
|
-
assert isinstance(config, UserConfig)
|
251
|
-
|
252
|
-
# Check default network
|
253
|
-
assert config.default_network == "localnet"
|
254
|
-
assert isinstance(config.networks["localnet"], NetworkConfigData)
|
255
|
-
assert config.networks["localnet"].id == 61999
|
256
|
-
assert config.networks["localnet"].url == "http://localhost:8545"
|
257
|
-
assert config.networks["localnet"].accounts == ["0x123", "0x456"]
|
258
|
-
assert config.networks["localnet"].from_account == "0x123"
|
259
|
-
|
260
|
-
# Check testnet_asimov network
|
261
|
-
assert isinstance(config.networks["testnet_asimov"], NetworkConfigData)
|
262
|
-
assert config.networks["testnet_asimov"].id == 4221
|
263
|
-
assert config.networks["testnet_asimov"].url == "http://34.32.169.58:9151"
|
264
|
-
assert config.networks["testnet_asimov"].accounts == ["0x123", "0x456"]
|
265
|
-
assert config.networks["testnet_asimov"].from_account == "0x123"
|
266
|
-
|
267
|
-
# Check paths
|
268
|
-
assert isinstance(config.paths, PathConfig)
|
269
|
-
assert config.paths.contracts == Path("contracts")
|
270
|
-
assert config.paths.artifacts == Path("artifacts")
|
271
|
-
|
272
|
-
# Check environment
|
273
|
-
assert config.environment == ".env"
|
274
|
-
|
275
|
-
|
276
|
-
def test_transform_raw_to_user_config_with_defaults():
|
277
|
-
# Test with empty config
|
278
|
-
config = transform_raw_to_user_config_with_defaults({})
|
279
|
-
assert isinstance(config, UserConfig)
|
280
|
-
assert all(key in config.__dict__ for key in VALID_ROOT_KEYS)
|
281
|
-
|
282
|
-
# Test with partial config
|
283
|
-
partial_config = {
|
284
|
-
"networks": {"default": "localnet", "localnet": {"url": "custom_url"}}
|
285
|
-
}
|
286
|
-
config = transform_raw_to_user_config_with_defaults(partial_config)
|
287
|
-
assert isinstance(config.networks["localnet"], NetworkConfigData)
|
288
|
-
assert config.networks["localnet"].url == "custom_url"
|
289
|
-
assert config.networks["localnet"].accounts is not None
|
290
|
-
assert config.networks["localnet"].from_account is not None
|
291
|
-
|
292
|
-
# Test with None network config
|
293
|
-
config = transform_raw_to_user_config_with_defaults(
|
294
|
-
{"networks": {"default": "localnet", "localnet": None}}
|
295
|
-
)
|
296
|
-
assert config.networks["localnet"] is not None
|
297
|
-
assert isinstance(config.networks["localnet"], NetworkConfigData)
|
298
|
-
|
299
|
-
# Test setting 'from' for non-default networks
|
300
|
-
test_config = {
|
301
|
-
"networks": {
|
302
|
-
"default": "localnet",
|
303
|
-
"localnet": {"url": "http://localhost:8545"},
|
304
|
-
"testnet": {"url": "http://testnet:8545", "accounts": ["0x123", "0x456"]},
|
305
|
-
"mainnet": {
|
306
|
-
"url": "http://mainnet:8545",
|
307
|
-
"accounts": ["0xabc", "0x789"],
|
308
|
-
"from": "0x789", # Already set
|
309
|
-
},
|
310
|
-
}
|
311
|
-
}
|
312
|
-
config = transform_raw_to_user_config_with_defaults(test_config)
|
313
|
-
|
314
|
-
# Verify testnet got 'from' set to first account
|
315
|
-
assert config.networks["testnet"].from_account == "0x123"
|
316
|
-
|
317
|
-
# Verify mainnet kept its existing 'from' value
|
318
|
-
assert config.networks["mainnet"].from_account == "0x789"
|
319
|
-
|
320
|
-
# Verify localnet (default network) behavior remains unchanged
|
321
|
-
assert config.networks["localnet"].from_account is not None
|
322
|
-
assert (
|
323
|
-
config.networks["localnet"].from_account in config.networks["localnet"].accounts
|
324
|
-
)
|
325
|
-
|
326
|
-
# Test with custom paths
|
327
|
-
custom_paths_config = {
|
328
|
-
"networks": {"default": "localnet"},
|
329
|
-
"paths": {"contracts": "custom/contracts/path"},
|
330
|
-
}
|
331
|
-
config = transform_raw_to_user_config_with_defaults(custom_paths_config)
|
332
|
-
assert config.paths.contracts == Path("custom/contracts/path")
|
333
|
-
|
334
|
-
# Test with custom environment
|
335
|
-
custom_env_config = {
|
336
|
-
"networks": {"default": "localnet"},
|
337
|
-
"environment": "custom.env",
|
338
|
-
}
|
339
|
-
config = transform_raw_to_user_config_with_defaults(custom_env_config)
|
340
|
-
assert config.environment == "custom.env"
|
341
|
-
|
342
|
-
|
343
|
-
@patch("pathlib.Path.cwd")
|
344
|
-
def test_user_config_exists(mock_cwd):
|
345
|
-
mock_path = MagicMock()
|
346
|
-
mock_cwd.return_value = mock_path
|
347
|
-
|
348
|
-
# Test when config exists
|
349
|
-
config_file = MagicMock()
|
350
|
-
config_file.name = "gltest.config.yaml"
|
351
|
-
config_file.is_file.return_value = True
|
352
|
-
mock_path.iterdir.return_value = [config_file]
|
353
|
-
assert user_config_exists() is True
|
354
|
-
|
355
|
-
# Test when config doesn't exist
|
356
|
-
other_file = MagicMock()
|
357
|
-
other_file.name = "other_file.txt"
|
358
|
-
other_file.is_file.return_value = True
|
359
|
-
mock_path.iterdir.return_value = [other_file]
|
360
|
-
assert user_config_exists() is False
|
361
|
-
|
362
|
-
# Test with no files
|
363
|
-
mock_path.iterdir.return_value = []
|
364
|
-
assert user_config_exists() is False
|
365
|
-
|
366
|
-
|
367
|
-
# Tests for artifacts directory functionality
|
368
|
-
def test_artifacts_path_in_config():
|
369
|
-
"""Test that artifacts path is properly handled in configuration."""
|
370
|
-
config_with_artifacts = {
|
371
|
-
"networks": {"default": "localnet"},
|
372
|
-
"paths": {"contracts": "contracts", "artifacts": "build/artifacts"},
|
373
|
-
}
|
374
|
-
|
375
|
-
config = transform_raw_to_user_config_with_defaults(config_with_artifacts)
|
376
|
-
assert config.paths.artifacts == Path("build/artifacts")
|
377
|
-
|
378
|
-
|
379
|
-
def test_artifacts_path_defaults():
|
380
|
-
"""Test that artifacts path defaults to DEFAULT_ARTIFACTS_DIR when not specified."""
|
381
|
-
config_without_artifacts = {
|
382
|
-
"networks": {"default": "localnet"},
|
383
|
-
"paths": {"contracts": "contracts"},
|
384
|
-
}
|
385
|
-
|
386
|
-
config = transform_raw_to_user_config_with_defaults(config_without_artifacts)
|
387
|
-
assert config.paths.artifacts == DEFAULT_ARTIFACTS_DIR
|
388
|
-
|
389
|
-
|
390
|
-
def test_artifacts_path_validation():
|
391
|
-
"""Test validation of artifacts path configuration."""
|
392
|
-
# Valid config with artifacts
|
393
|
-
valid_config = {"paths": {"artifacts": "custom/artifacts"}}
|
394
|
-
validate_raw_user_config(valid_config) # Should not raise
|
395
|
-
|
396
|
-
# Test that artifacts is included in valid path keys
|
397
|
-
from gltest_cli.config.user import VALID_PATHS_KEYS
|
398
|
-
|
399
|
-
assert "artifacts" in VALID_PATHS_KEYS
|
400
|
-
|
401
|
-
|
402
|
-
def test_artifacts_path_only_config():
|
403
|
-
"""Test configuration with only artifacts path specified."""
|
404
|
-
config_artifacts_only = {
|
405
|
-
"networks": {"default": "localnet"},
|
406
|
-
"paths": {"artifacts": "my_artifacts"},
|
407
|
-
}
|
408
|
-
|
409
|
-
config = transform_raw_to_user_config_with_defaults(config_artifacts_only)
|
410
|
-
assert config.paths.contracts == DEFAULT_CONTRACTS_DIR
|
411
|
-
assert config.paths.artifacts == Path("my_artifacts")
|
File without changes
|
File without changes
|
File without changes
|