v2kit 0.4__tar.gz → 0.6__tar.gz
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.
- {v2kit-0.4 → v2kit-0.6}/CHANGELOG.md +31 -1
- {v2kit-0.4 → v2kit-0.6}/PKG-INFO +36 -6
- {v2kit-0.4 → v2kit-0.6}/README.md +2 -2
- {v2kit-0.4 → v2kit-0.6}/SECURITY.md +2 -2
- {v2kit-0.4 → v2kit-0.6}/setup.py +3 -3
- {v2kit-0.4 → v2kit-0.6}/tests/test_errors.py +30 -3
- {v2kit-0.4 → v2kit-0.6}/tests/test_functions.py +9 -1
- {v2kit-0.4 → v2kit-0.6}/tests/test_http.py +75 -1
- {v2kit-0.4 → v2kit-0.6}/tests/test_shadowsocks.py +88 -2
- {v2kit-0.4 → v2kit-0.6}/tests/test_socks.py +79 -1
- {v2kit-0.4 → v2kit-0.6}/tests/test_trojan.py +88 -1
- {v2kit-0.4 → v2kit-0.6}/tests/test_vless.py +83 -1
- {v2kit-0.4 → v2kit-0.6}/tests/test_vmess.py +117 -1
- {v2kit-0.4 → v2kit-0.6}/v2kit/functions.py +14 -35
- {v2kit-0.4 → v2kit-0.6}/v2kit/models/base.py +67 -15
- {v2kit-0.4 → v2kit-0.6}/v2kit/models/http.py +7 -18
- {v2kit-0.4 → v2kit-0.6}/v2kit/models/shadowsocks.py +11 -30
- {v2kit-0.4 → v2kit-0.6}/v2kit/models/socks.py +9 -27
- {v2kit-0.4 → v2kit-0.6}/v2kit/models/trojan.py +8 -22
- {v2kit-0.4 → v2kit-0.6}/v2kit/models/vless.py +8 -22
- {v2kit-0.4 → v2kit-0.6}/v2kit/models/vmess.py +10 -33
- {v2kit-0.4 → v2kit-0.6}/v2kit/params.py +15 -3
- {v2kit-0.4 → v2kit-0.6}/v2kit/parsers.py +64 -78
- {v2kit-0.4 → v2kit-0.6}/v2kit/utils.py +6 -9
- {v2kit-0.4 → v2kit-0.6}/v2kit/validators.py +7 -13
- {v2kit-0.4 → v2kit-0.6}/v2kit.egg-info/PKG-INFO +36 -6
- {v2kit-0.4 → v2kit-0.6}/AUTHORS.md +0 -0
- {v2kit-0.4 → v2kit-0.6}/LICENSE +0 -0
- {v2kit-0.4 → v2kit-0.6}/MANIFEST.in +0 -0
- {v2kit-0.4 → v2kit-0.6}/requirements-dev.txt +0 -0
- {v2kit-0.4 → v2kit-0.6}/setup.cfg +0 -0
- {v2kit-0.4 → v2kit-0.6}/v2kit/__init__.py +0 -0
- {v2kit-0.4 → v2kit-0.6}/v2kit/__main__.py +0 -0
- {v2kit-0.4 → v2kit-0.6}/v2kit/errors.py +0 -0
- {v2kit-0.4 → v2kit-0.6}/v2kit/models/__init__.py +0 -0
- {v2kit-0.4 → v2kit-0.6}/v2kit.egg-info/SOURCES.txt +0 -0
- {v2kit-0.4 → v2kit-0.6}/v2kit.egg-info/dependency_links.txt +0 -0
- {v2kit-0.4 → v2kit-0.6}/v2kit.egg-info/top_level.txt +0 -0
|
@@ -5,6 +5,34 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
|
+
## [0.6] - 2026-09-01
|
|
9
|
+
### Added
|
|
10
|
+
- `clear_extra` method
|
|
11
|
+
- `set_extra_item` method
|
|
12
|
+
- `get_extra_item` method
|
|
13
|
+
- `remove_extra_item` method
|
|
14
|
+
### Changed
|
|
15
|
+
- `_get_protocol` function modified
|
|
16
|
+
- `decode_subscription` function blank line bug fixed
|
|
17
|
+
- Port validation bug fixed
|
|
18
|
+
- AlterId validation bug fixed
|
|
19
|
+
- Test system modified
|
|
20
|
+
- Parsers updated
|
|
21
|
+
## [0.5] - 2026-07-31
|
|
22
|
+
### Added
|
|
23
|
+
- `encoded_label` property
|
|
24
|
+
- `uri_label` property
|
|
25
|
+
### Changed
|
|
26
|
+
- `encode_subscription` function modified
|
|
27
|
+
- `parse` function modified
|
|
28
|
+
- `extra` property modified
|
|
29
|
+
- `update_extra` method modified
|
|
30
|
+
- `to_uri` method modified
|
|
31
|
+
- `to_dict` method modified
|
|
32
|
+
- `Protocol` enum updated
|
|
33
|
+
- Scheme bug fixed
|
|
34
|
+
- VMESS parser bug fixed
|
|
35
|
+
- Test system modified
|
|
8
36
|
## [0.4] - 2026-07-02
|
|
9
37
|
### Added
|
|
10
38
|
- `HttpConfig` class
|
|
@@ -50,7 +78,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
|
50
78
|
- `encode_subscription` function
|
|
51
79
|
- `decode_subscription` function
|
|
52
80
|
|
|
53
|
-
[Unreleased]: https://github.com/sepandhaghighi/v2kit/compare/v0.
|
|
81
|
+
[Unreleased]: https://github.com/sepandhaghighi/v2kit/compare/v0.6...dev
|
|
82
|
+
[0.6]: https://github.com/sepandhaghighi/v2kit/compare/v0.5...v0.6
|
|
83
|
+
[0.5]: https://github.com/sepandhaghighi/v2kit/compare/v0.4...v0.5
|
|
54
84
|
[0.4]: https://github.com/sepandhaghighi/v2kit/compare/v0.3...v0.4
|
|
55
85
|
[0.3]: https://github.com/sepandhaghighi/v2kit/compare/v0.2...v0.3
|
|
56
86
|
[0.2]: https://github.com/sepandhaghighi/v2kit/compare/v0.1...v0.2
|
{v2kit-0.4 → v2kit-0.6}/PKG-INFO
RENAMED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: v2kit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6
|
|
4
4
|
Summary: V2Kit: A Lightweight Toolkit for V2Ray Config Manipulation
|
|
5
5
|
Home-page: https://github.com/sepandhaghighi/v2kit
|
|
6
|
-
Download-URL: https://github.com/sepandhaghighi/v2kit/tarball/v0.
|
|
6
|
+
Download-URL: https://github.com/sepandhaghighi/v2kit/tarball/v0.6
|
|
7
7
|
Author: Sepand Haghighi
|
|
8
8
|
Author-email: me@sepand.tech
|
|
9
9
|
License: MIT
|
|
10
10
|
Project-URL: Source, https://github.com/sepandhaghighi/v2kit
|
|
11
11
|
Keywords: v2ray v2ray-config v2ray-tools vmess vless trojan shadowsocks proxy subscription network
|
|
12
|
-
Classifier: Development Status ::
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
13
|
Classifier: Natural Language :: English
|
|
14
14
|
Classifier: License :: OSI Approved :: MIT License
|
|
15
15
|
Classifier: Operating System :: OS Independent
|
|
@@ -96,13 +96,13 @@ V2Kit is a lightweight and extensible Python toolkit for working with V2Ray prox
|
|
|
96
96
|
## Installation
|
|
97
97
|
|
|
98
98
|
### Source Code
|
|
99
|
-
- Download [Version 0.
|
|
99
|
+
- Download [Version 0.6](https://github.com/sepandhaghighi/v2kit/archive/v0.6.zip) or [Latest Source](https://github.com/sepandhaghighi/v2kit/archive/dev.zip)
|
|
100
100
|
- `pip install .`
|
|
101
101
|
|
|
102
102
|
### PyPI
|
|
103
103
|
|
|
104
104
|
- Check [Python Packaging User Guide](https://packaging.python.org/installing/)
|
|
105
|
-
- `pip install v2kit==0.
|
|
105
|
+
- `pip install v2kit==0.6`
|
|
106
106
|
|
|
107
107
|
## Supported Protocols
|
|
108
108
|
|
|
@@ -211,6 +211,34 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
|
211
211
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
212
212
|
|
|
213
213
|
## [Unreleased]
|
|
214
|
+
## [0.6] - 2026-09-01
|
|
215
|
+
### Added
|
|
216
|
+
- `clear_extra` method
|
|
217
|
+
- `set_extra_item` method
|
|
218
|
+
- `get_extra_item` method
|
|
219
|
+
- `remove_extra_item` method
|
|
220
|
+
### Changed
|
|
221
|
+
- `_get_protocol` function modified
|
|
222
|
+
- `decode_subscription` function blank line bug fixed
|
|
223
|
+
- Port validation bug fixed
|
|
224
|
+
- AlterId validation bug fixed
|
|
225
|
+
- Test system modified
|
|
226
|
+
- Parsers updated
|
|
227
|
+
## [0.5] - 2026-07-31
|
|
228
|
+
### Added
|
|
229
|
+
- `encoded_label` property
|
|
230
|
+
- `uri_label` property
|
|
231
|
+
### Changed
|
|
232
|
+
- `encode_subscription` function modified
|
|
233
|
+
- `parse` function modified
|
|
234
|
+
- `extra` property modified
|
|
235
|
+
- `update_extra` method modified
|
|
236
|
+
- `to_uri` method modified
|
|
237
|
+
- `to_dict` method modified
|
|
238
|
+
- `Protocol` enum updated
|
|
239
|
+
- Scheme bug fixed
|
|
240
|
+
- VMESS parser bug fixed
|
|
241
|
+
- Test system modified
|
|
214
242
|
## [0.4] - 2026-07-02
|
|
215
243
|
### Added
|
|
216
244
|
- `HttpConfig` class
|
|
@@ -256,7 +284,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
|
256
284
|
- `encode_subscription` function
|
|
257
285
|
- `decode_subscription` function
|
|
258
286
|
|
|
259
|
-
[Unreleased]: https://github.com/sepandhaghighi/v2kit/compare/v0.
|
|
287
|
+
[Unreleased]: https://github.com/sepandhaghighi/v2kit/compare/v0.6...dev
|
|
288
|
+
[0.6]: https://github.com/sepandhaghighi/v2kit/compare/v0.5...v0.6
|
|
289
|
+
[0.5]: https://github.com/sepandhaghighi/v2kit/compare/v0.4...v0.5
|
|
260
290
|
[0.4]: https://github.com/sepandhaghighi/v2kit/compare/v0.3...v0.4
|
|
261
291
|
[0.3]: https://github.com/sepandhaghighi/v2kit/compare/v0.2...v0.3
|
|
262
292
|
[0.2]: https://github.com/sepandhaghighi/v2kit/compare/v0.1...v0.2
|
|
@@ -51,13 +51,13 @@ V2Kit is a lightweight and extensible Python toolkit for working with V2Ray prox
|
|
|
51
51
|
## Installation
|
|
52
52
|
|
|
53
53
|
### Source Code
|
|
54
|
-
- Download [Version 0.
|
|
54
|
+
- Download [Version 0.6](https://github.com/sepandhaghighi/v2kit/archive/v0.6.zip) or [Latest Source](https://github.com/sepandhaghighi/v2kit/archive/dev.zip)
|
|
55
55
|
- `pip install .`
|
|
56
56
|
|
|
57
57
|
### PyPI
|
|
58
58
|
|
|
59
59
|
- Check [Python Packaging User Guide](https://packaging.python.org/installing/)
|
|
60
|
-
- `pip install v2kit==0.
|
|
60
|
+
- `pip install v2kit==0.6`
|
|
61
61
|
|
|
62
62
|
## Supported Protocols
|
|
63
63
|
|
{v2kit-0.4 → v2kit-0.6}/setup.py
RENAMED
|
@@ -23,7 +23,7 @@ def read_description() -> str:
|
|
|
23
23
|
setup(
|
|
24
24
|
name='v2kit',
|
|
25
25
|
packages=['v2kit', 'v2kit.models'],
|
|
26
|
-
version='0.
|
|
26
|
+
version='0.6',
|
|
27
27
|
description='V2Kit: A Lightweight Toolkit for V2Ray Config Manipulation',
|
|
28
28
|
long_description=read_description(),
|
|
29
29
|
long_description_content_type='text/markdown',
|
|
@@ -31,14 +31,14 @@ setup(
|
|
|
31
31
|
author='Sepand Haghighi',
|
|
32
32
|
author_email='me@sepand.tech',
|
|
33
33
|
url='https://github.com/sepandhaghighi/v2kit',
|
|
34
|
-
download_url='https://github.com/sepandhaghighi/v2kit/tarball/v0.
|
|
34
|
+
download_url='https://github.com/sepandhaghighi/v2kit/tarball/v0.6',
|
|
35
35
|
keywords='v2ray v2ray-config v2ray-tools vmess vless trojan shadowsocks proxy subscription network',
|
|
36
36
|
project_urls={
|
|
37
37
|
'Source': 'https://github.com/sepandhaghighi/v2kit'},
|
|
38
38
|
install_requires=[],
|
|
39
39
|
python_requires='>=3.8',
|
|
40
40
|
classifiers=[
|
|
41
|
-
'Development Status ::
|
|
41
|
+
'Development Status :: 4 - Beta',
|
|
42
42
|
'Natural Language :: English',
|
|
43
43
|
'License :: OSI Approved :: MIT License',
|
|
44
44
|
'Operating System :: OS Independent',
|
|
@@ -143,7 +143,7 @@ def test_vless_invalid_uuid():
|
|
|
143
143
|
)
|
|
144
144
|
|
|
145
145
|
|
|
146
|
-
def
|
|
146
|
+
def test_vless_invalid_port1():
|
|
147
147
|
with pytest.raises(V2kitValidationError):
|
|
148
148
|
VLESSConfig(
|
|
149
149
|
uuid=VALID_UUID,
|
|
@@ -152,6 +152,15 @@ def test_vless_invalid_port():
|
|
|
152
152
|
)
|
|
153
153
|
|
|
154
154
|
|
|
155
|
+
def test_vless_invalid_port2():
|
|
156
|
+
with pytest.raises(V2kitValidationError):
|
|
157
|
+
VLESSConfig(
|
|
158
|
+
uuid=VALID_UUID,
|
|
159
|
+
address="example.com",
|
|
160
|
+
port=True,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
|
|
155
164
|
def test_vless_empty_address():
|
|
156
165
|
with pytest.raises(V2kitValidationError):
|
|
157
166
|
VLESSConfig(
|
|
@@ -161,7 +170,7 @@ def test_vless_empty_address():
|
|
|
161
170
|
)
|
|
162
171
|
|
|
163
172
|
|
|
164
|
-
def
|
|
173
|
+
def test_vmess_invalid_alter_id1():
|
|
165
174
|
with pytest.raises(V2kitValidationError):
|
|
166
175
|
VMESSConfig(
|
|
167
176
|
uuid=VALID_UUID,
|
|
@@ -171,6 +180,16 @@ def test_vmess_invalid_alter_id():
|
|
|
171
180
|
)
|
|
172
181
|
|
|
173
182
|
|
|
183
|
+
def test_vmess_invalid_alter_id2():
|
|
184
|
+
with pytest.raises(V2kitValidationError):
|
|
185
|
+
VMESSConfig(
|
|
186
|
+
uuid=VALID_UUID,
|
|
187
|
+
address="example.com",
|
|
188
|
+
port=443,
|
|
189
|
+
alter_id=True,
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
|
|
174
193
|
def test_trojan_empty_password():
|
|
175
194
|
with pytest.raises(V2kitValidationError):
|
|
176
195
|
TrojanConfig(
|
|
@@ -190,7 +209,7 @@ def test_shadowsocks_empty_encryption():
|
|
|
190
209
|
)
|
|
191
210
|
|
|
192
211
|
|
|
193
|
-
def
|
|
212
|
+
def test_socks_invalid_port1():
|
|
194
213
|
with pytest.raises(V2kitValidationError):
|
|
195
214
|
SocksConfig(
|
|
196
215
|
address="example.com",
|
|
@@ -198,6 +217,14 @@ def test_socks_invalid_port():
|
|
|
198
217
|
)
|
|
199
218
|
|
|
200
219
|
|
|
220
|
+
def test_socks_invalid_port2():
|
|
221
|
+
with pytest.raises(V2kitValidationError):
|
|
222
|
+
SocksConfig(
|
|
223
|
+
address="example.com",
|
|
224
|
+
port=False,
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
|
|
201
228
|
def test_socks_empty_address():
|
|
202
229
|
with pytest.raises(V2kitValidationError):
|
|
203
230
|
SocksConfig(
|
|
@@ -135,7 +135,7 @@ def test_encode_subscription():
|
|
|
135
135
|
assert len(result) > 0
|
|
136
136
|
|
|
137
137
|
|
|
138
|
-
def
|
|
138
|
+
def test_decode_subscription1():
|
|
139
139
|
configs = [
|
|
140
140
|
VMESS_CONFIG,
|
|
141
141
|
VLESS_CONFIG,
|
|
@@ -148,6 +148,14 @@ def test_decode_subscription():
|
|
|
148
148
|
assert result == configs
|
|
149
149
|
|
|
150
150
|
|
|
151
|
+
def test_decode_subscription2():
|
|
152
|
+
subscription = "dmxlc3M6Ly8xYzRiNGJjYS1lM2ZmLTRjYTgtYTA2Mi02ZjM5OWFkM2NmNDVAZXhhbXBsZS5jb206NDQzP3NlY3VyaXR5PXRscyN2bGVzcy10ZXN0Cgp0cm9qYW46Ly9wYXNzd29yZEBleGFtcGxlLmNvbTo0NDM/c2VjdXJpdHk9dGxzI3Ryb2phbi10ZXN0CgpzczovL1lXVnpMVEkxTmkxblkyMDZjR0Z6YzNkdmNtUT1AZXhhbXBsZS5jb206ODM4OCNzcy10ZXN0Cg=="
|
|
153
|
+
|
|
154
|
+
result = decode_subscription(subscription)
|
|
155
|
+
|
|
156
|
+
assert len(result) == 3
|
|
157
|
+
|
|
158
|
+
|
|
151
159
|
def test_encode_decode_subscription_roundtrip():
|
|
152
160
|
configs = [
|
|
153
161
|
VMESS_CONFIG,
|
|
@@ -79,6 +79,59 @@ def test_update_extra():
|
|
|
79
79
|
assert config.extra["foo"] == "bar"
|
|
80
80
|
|
|
81
81
|
|
|
82
|
+
def test_clear_extra():
|
|
83
|
+
config = HttpConfig(
|
|
84
|
+
address="example.com",
|
|
85
|
+
port=1080,
|
|
86
|
+
extra={"foo": "bar"},
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
config.clear_extra()
|
|
90
|
+
|
|
91
|
+
assert config.extra == {}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def test_set_extra_item():
|
|
95
|
+
config = HttpConfig(
|
|
96
|
+
address="example.com",
|
|
97
|
+
port=1080,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
config.set_extra_item(
|
|
101
|
+
"foo",
|
|
102
|
+
"bar",
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
assert config.extra["foo"] == "bar"
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def test_get_extra_item():
|
|
109
|
+
config = HttpConfig(
|
|
110
|
+
address="example.com",
|
|
111
|
+
port=1080,
|
|
112
|
+
extra={"foo": "bar"},
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
assert config.get_extra_item("foo") == "bar"
|
|
116
|
+
assert config.get_extra_item("missing") is None
|
|
117
|
+
assert config.get_extra_item(
|
|
118
|
+
"missing",
|
|
119
|
+
"default",
|
|
120
|
+
) == "default"
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def test_remove_extra_item():
|
|
124
|
+
config = HttpConfig(
|
|
125
|
+
address="example.com",
|
|
126
|
+
port=1080,
|
|
127
|
+
extra={"foo": "bar"},
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
config.remove_extra_item("foo")
|
|
131
|
+
|
|
132
|
+
assert config.extra == {}
|
|
133
|
+
|
|
134
|
+
|
|
82
135
|
def test_method_chaining():
|
|
83
136
|
config = HttpConfig(
|
|
84
137
|
address="example.com",
|
|
@@ -93,12 +146,18 @@ def test_method_chaining():
|
|
|
93
146
|
"user"
|
|
94
147
|
).update_password(
|
|
95
148
|
"password"
|
|
96
|
-
)
|
|
149
|
+
).set_extra_item(
|
|
150
|
+
"foo",
|
|
151
|
+
"bar",
|
|
152
|
+
).remove_extra_item(
|
|
153
|
+
"foo"
|
|
154
|
+
).clear_extra()
|
|
97
155
|
|
|
98
156
|
assert config.address == "example.org"
|
|
99
157
|
assert config.port == 8080
|
|
100
158
|
assert config.username == "user"
|
|
101
159
|
assert config.password == "password"
|
|
160
|
+
assert config.extra == {}
|
|
102
161
|
|
|
103
162
|
|
|
104
163
|
@pytest.mark.parametrize(
|
|
@@ -137,6 +196,21 @@ def test_to_uri_roundtrip():
|
|
|
137
196
|
assert parsed == config
|
|
138
197
|
|
|
139
198
|
|
|
199
|
+
def test_encoded_label():
|
|
200
|
+
config = HttpConfig(
|
|
201
|
+
address="example.com",
|
|
202
|
+
port=1080,
|
|
203
|
+
username="user",
|
|
204
|
+
password="password",
|
|
205
|
+
label="test 1 2",
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
parsed = parse(config.to_uri())
|
|
209
|
+
assert parsed == config
|
|
210
|
+
assert config.label == "test 1 2"
|
|
211
|
+
assert config.encoded_label == "test%201%202"
|
|
212
|
+
|
|
213
|
+
|
|
140
214
|
def test_equality():
|
|
141
215
|
config1 = HttpConfig(
|
|
142
216
|
address="example.com",
|
|
@@ -67,12 +67,18 @@ def test_method_chaining():
|
|
|
67
67
|
"example.org"
|
|
68
68
|
).update_port(
|
|
69
69
|
443
|
|
70
|
-
)
|
|
70
|
+
).set_extra_item(
|
|
71
|
+
"plugin",
|
|
72
|
+
"v2ray-plugin",
|
|
73
|
+
).remove_extra_item(
|
|
74
|
+
"plugin"
|
|
75
|
+
).clear_extra()
|
|
71
76
|
|
|
72
77
|
assert config.encryption == "chacha20-ietf-poly1305"
|
|
73
78
|
assert config.password == "secret"
|
|
74
79
|
assert config.address == "example.org"
|
|
75
80
|
assert config.port == 443
|
|
81
|
+
assert config.extra == {}
|
|
76
82
|
|
|
77
83
|
|
|
78
84
|
@pytest.mark.parametrize(
|
|
@@ -113,6 +119,21 @@ def test_to_uri_roundtrip():
|
|
|
113
119
|
assert parsed == config
|
|
114
120
|
|
|
115
121
|
|
|
122
|
+
def test_encoded_label():
|
|
123
|
+
config = ShadowsocksConfig(
|
|
124
|
+
encryption="aes-256-gcm",
|
|
125
|
+
password="password",
|
|
126
|
+
address="example.com",
|
|
127
|
+
port=8388,
|
|
128
|
+
label="test 1 2",
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
parsed = parse(config.to_uri())
|
|
132
|
+
assert parsed == config
|
|
133
|
+
assert config.label == "test 1 2"
|
|
134
|
+
assert config.encoded_label == "test%201%202"
|
|
135
|
+
|
|
136
|
+
|
|
116
137
|
def test_equality():
|
|
117
138
|
config1 = ShadowsocksConfig(
|
|
118
139
|
encryption="aes-256-gcm",
|
|
@@ -150,7 +171,7 @@ def test_repr():
|
|
|
150
171
|
|
|
151
172
|
assert repr(config) == (
|
|
152
173
|
"ShadowsocksConfig(protocol=<Protocol.SHADOWSOCKS: "
|
|
153
|
-
"'
|
|
174
|
+
"'shadowsocks'>, label=None)"
|
|
154
175
|
)
|
|
155
176
|
|
|
156
177
|
|
|
@@ -169,6 +190,71 @@ def test_update_extra():
|
|
|
169
190
|
assert config.extra["plugin"] == "v2ray-plugin"
|
|
170
191
|
|
|
171
192
|
|
|
193
|
+
def test_clear_extra():
|
|
194
|
+
config = ShadowsocksConfig(
|
|
195
|
+
encryption="aes-256-gcm",
|
|
196
|
+
password="password",
|
|
197
|
+
address="example.com",
|
|
198
|
+
port=8388,
|
|
199
|
+
extra={"plugin": "v2ray-plugin"},
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
config.clear_extra()
|
|
203
|
+
|
|
204
|
+
assert config.extra == {}
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def test_set_extra_item():
|
|
208
|
+
config = ShadowsocksConfig(
|
|
209
|
+
encryption="aes-256-gcm",
|
|
210
|
+
password="password",
|
|
211
|
+
address="example.com",
|
|
212
|
+
port=8388,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
config.set_extra_item(
|
|
216
|
+
"plugin",
|
|
217
|
+
"v2ray-plugin",
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
assert config.extra["plugin"] == "v2ray-plugin"
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def test_get_extra_item():
|
|
224
|
+
config = ShadowsocksConfig(
|
|
225
|
+
encryption="aes-256-gcm",
|
|
226
|
+
password="password",
|
|
227
|
+
address="example.com",
|
|
228
|
+
port=8388,
|
|
229
|
+
extra={"plugin": "v2ray-plugin"},
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
assert config.get_extra_item(
|
|
233
|
+
"plugin"
|
|
234
|
+
) == "v2ray-plugin"
|
|
235
|
+
assert config.get_extra_item("missing") is None
|
|
236
|
+
assert config.get_extra_item(
|
|
237
|
+
"missing",
|
|
238
|
+
"default",
|
|
239
|
+
) == "default"
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def test_remove_extra_item():
|
|
243
|
+
config = ShadowsocksConfig(
|
|
244
|
+
encryption="aes-256-gcm",
|
|
245
|
+
password="password",
|
|
246
|
+
address="example.com",
|
|
247
|
+
port=8388,
|
|
248
|
+
extra={"plugin": "v2ray-plugin"},
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
config.remove_extra_item(
|
|
252
|
+
"plugin"
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
assert config.extra == {}
|
|
256
|
+
|
|
257
|
+
|
|
172
258
|
def test_update_methods():
|
|
173
259
|
config = ShadowsocksConfig(
|
|
174
260
|
encryption="aes-256-gcm",
|
|
@@ -61,12 +61,18 @@ def test_method_chaining():
|
|
|
61
61
|
"user"
|
|
62
62
|
).update_password(
|
|
63
63
|
"password"
|
|
64
|
-
)
|
|
64
|
+
).set_extra_item(
|
|
65
|
+
"version",
|
|
66
|
+
"5",
|
|
67
|
+
).remove_extra_item(
|
|
68
|
+
"version"
|
|
69
|
+
).clear_extra()
|
|
65
70
|
|
|
66
71
|
assert config.address == "example.org"
|
|
67
72
|
assert config.port == 2080
|
|
68
73
|
assert config.username == "user"
|
|
69
74
|
assert config.password == "password"
|
|
75
|
+
assert config.extra == {}
|
|
70
76
|
|
|
71
77
|
|
|
72
78
|
@pytest.mark.parametrize(
|
|
@@ -121,6 +127,63 @@ def test_update_extra():
|
|
|
121
127
|
assert config.extra["version"] == "5"
|
|
122
128
|
|
|
123
129
|
|
|
130
|
+
def test_clear_extra():
|
|
131
|
+
config = SocksConfig(
|
|
132
|
+
address="example.com",
|
|
133
|
+
port=1080,
|
|
134
|
+
extra={"version": "5"},
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
config.clear_extra()
|
|
138
|
+
|
|
139
|
+
assert config.extra == {}
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def test_set_extra_item():
|
|
143
|
+
config = SocksConfig(
|
|
144
|
+
address="example.com",
|
|
145
|
+
port=1080,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
config.set_extra_item(
|
|
149
|
+
"version",
|
|
150
|
+
"5",
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
assert config.extra["version"] == "5"
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def test_get_extra_item():
|
|
157
|
+
config = SocksConfig(
|
|
158
|
+
address="example.com",
|
|
159
|
+
port=1080,
|
|
160
|
+
extra={"version": "5"},
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
assert config.get_extra_item(
|
|
164
|
+
"version"
|
|
165
|
+
) == "5"
|
|
166
|
+
assert config.get_extra_item("missing") is None
|
|
167
|
+
assert config.get_extra_item(
|
|
168
|
+
"missing",
|
|
169
|
+
"default",
|
|
170
|
+
) == "default"
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def test_remove_extra_item():
|
|
174
|
+
config = SocksConfig(
|
|
175
|
+
address="example.com",
|
|
176
|
+
port=1080,
|
|
177
|
+
extra={"version": "5"},
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
config.remove_extra_item(
|
|
181
|
+
"version"
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
assert config.extra == {}
|
|
185
|
+
|
|
186
|
+
|
|
124
187
|
def test_to_uri_roundtrip():
|
|
125
188
|
config = SocksConfig(
|
|
126
189
|
address="example.com",
|
|
@@ -135,6 +198,21 @@ def test_to_uri_roundtrip():
|
|
|
135
198
|
assert parsed == config
|
|
136
199
|
|
|
137
200
|
|
|
201
|
+
def test_encoded_label():
|
|
202
|
+
config = SocksConfig(
|
|
203
|
+
address="example.com",
|
|
204
|
+
port=1080,
|
|
205
|
+
username="user",
|
|
206
|
+
password="password",
|
|
207
|
+
label="test 1 2",
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
parsed = parse(config.to_uri())
|
|
211
|
+
assert parsed == config
|
|
212
|
+
assert config.label == "test 1 2"
|
|
213
|
+
assert config.encoded_label == "test%201%202"
|
|
214
|
+
|
|
215
|
+
|
|
138
216
|
def test_equality():
|
|
139
217
|
config1 = SocksConfig(
|
|
140
218
|
address="example.com",
|