jit-utils-backend 0.0.1__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.
- jit_utils/__init__.py +152 -0
- jit_utils/apiAuthSign.py +73 -0
- jit_utils/barcode.py +50 -0
- jit_utils/clsTool.py +71 -0
- jit_utils/config/__init__.py +11 -0
- jit_utils/config/case.py +77 -0
- jit_utils/config/config.py +90 -0
- jit_utils/config/exception.py +17 -0
- jit_utils/config/field.py +177 -0
- jit_utils/convert.py +169 -0
- jit_utils/decorator.py +58 -0
- jit_utils/exceptions.py +113 -0
- jit_utils/forwarder.py +113 -0
- jit_utils/matchTool.py +136 -0
- jit_utils/network.py +36 -0
- jit_utils/qrcode.py +60 -0
- jit_utils/signature.py +56 -0
- jit_utils/spaceSender.py +44 -0
- jit_utils/string.py +118 -0
- jit_utils/time.py +701 -0
- jit_utils/validator.py +26 -0
- jit_utils/workday_constants.py +72 -0
- jit_utils_backend-0.0.1.dist-info/METADATA +182 -0
- jit_utils_backend-0.0.1.dist-info/RECORD +32 -0
- jit_utils_backend-0.0.1.dist-info/WHEEL +5 -0
- jit_utils_backend-0.0.1.dist-info/top_level.txt +2 -0
- tests/__init__.py +4 -0
- tests/run_tests.py +102 -0
- tests/test_package_imports.py +199 -0
- tests/test_qrcode_barcode.py +182 -0
- tests/test_string_utils.py +174 -0
- tests/test_time_utils.py +185 -0
jit_utils/validator.py
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
from dataclasses import MISSING, dataclass, fields
|
2
|
+
|
3
|
+
from commons.errcode import ElementErrorCode
|
4
|
+
|
5
|
+
|
6
|
+
@dataclass
|
7
|
+
class ParamsValidator:
|
8
|
+
|
9
|
+
def __init__(self, __fullName__, **kwargs):
|
10
|
+
for fieldInfo in fields(self):
|
11
|
+
fieldName = fieldInfo.name
|
12
|
+
if fieldName not in kwargs:
|
13
|
+
# 没有默认值
|
14
|
+
if fieldInfo.default is MISSING:
|
15
|
+
raise ElementErrorCode.PARAMS_MISSING_ERROR.formatReason(fullName=__fullName__, fieldName=fieldName)
|
16
|
+
|
17
|
+
value = kwargs.get(fieldName, fieldInfo.default)
|
18
|
+
try:
|
19
|
+
value = fieldInfo.type(value)
|
20
|
+
except ValueError:
|
21
|
+
raise ElementErrorCode.PARAMS_TYPE_ERROR.formatReason(
|
22
|
+
fullName=__fullName__, expect=fieldInfo.type.__name__, actual=type(value).__name__
|
23
|
+
)
|
24
|
+
setattr(self, fieldName, value)
|
25
|
+
if hasattr(self, "__post_init__"):
|
26
|
+
self.__post_init__(__fullName__)
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# -*-coding:utf-8-*-
|
2
|
+
"""
|
3
|
+
Created on 2023/10/21
|
4
|
+
|
5
|
+
@author: wanjianjun
|
6
|
+
|
7
|
+
@desc:
|
8
|
+
"""
|
9
|
+
import datetime
|
10
|
+
from enum import Enum
|
11
|
+
|
12
|
+
|
13
|
+
class Holiday(Enum):
|
14
|
+
def __new__(cls, english, chinese, days):
|
15
|
+
obj = object.__new__(cls)
|
16
|
+
obj._value = english
|
17
|
+
|
18
|
+
obj.chinese = chinese
|
19
|
+
obj.days = days
|
20
|
+
return obj
|
21
|
+
|
22
|
+
newYearsDay = "New Year's Day", "元旦", 3
|
23
|
+
springFestival = "Spring Festival", "春节", 7
|
24
|
+
tombSweepingDay = "Tomb-sweeping Day", "清明", 3
|
25
|
+
labourDay = "Labour Day", "劳动节", 5
|
26
|
+
dragonBoatFestival = "Dragon Boat Festival", "端午", 3
|
27
|
+
nationalDay = "National Day", "国庆节", 7
|
28
|
+
midAutumnFestival = "Mid-autumn Festival", "中秋", 3
|
29
|
+
|
30
|
+
|
31
|
+
holidayDict = {
|
32
|
+
datetime.date(year=2024, month=1, day=1).strftime("%Y-%m-%d"): Holiday.newYearsDay.value,
|
33
|
+
datetime.date(year=2024, month=2, day=10).strftime("%Y-%m-%d"): Holiday.springFestival.value,
|
34
|
+
datetime.date(year=2024, month=2, day=11).strftime("%Y-%m-%d"): Holiday.springFestival.value,
|
35
|
+
datetime.date(year=2024, month=2, day=12).strftime("%Y-%m-%d"): Holiday.springFestival.value,
|
36
|
+
datetime.date(year=2024, month=2, day=13).strftime("%Y-%m-%d"): Holiday.springFestival.value,
|
37
|
+
datetime.date(year=2024, month=2, day=14).strftime("%Y-%m-%d"): Holiday.springFestival.value,
|
38
|
+
datetime.date(year=2024, month=2, day=15).strftime("%Y-%m-%d"): Holiday.springFestival.value,
|
39
|
+
datetime.date(year=2024, month=2, day=16).strftime("%Y-%m-%d"): Holiday.springFestival.value,
|
40
|
+
datetime.date(year=2024, month=2, day=17).strftime("%Y-%m-%d"): Holiday.springFestival.value,
|
41
|
+
datetime.date(year=2024, month=4, day=4).strftime("%Y-%m-%d"): Holiday.tombSweepingDay.value,
|
42
|
+
datetime.date(year=2024, month=4, day=5).strftime("%Y-%m-%d"): Holiday.tombSweepingDay.value,
|
43
|
+
datetime.date(year=2024, month=4, day=6).strftime("%Y-%m-%d"): Holiday.tombSweepingDay.value,
|
44
|
+
datetime.date(year=2024, month=5, day=1).strftime("%Y-%m-%d"): Holiday.labourDay.value,
|
45
|
+
datetime.date(year=2024, month=5, day=2).strftime("%Y-%m-%d"): Holiday.labourDay.value,
|
46
|
+
datetime.date(year=2024, month=5, day=3).strftime("%Y-%m-%d"): Holiday.labourDay.value,
|
47
|
+
datetime.date(year=2024, month=5, day=4).strftime("%Y-%m-%d"): Holiday.labourDay.value,
|
48
|
+
datetime.date(year=2024, month=5, day=5).strftime("%Y-%m-%d"): Holiday.labourDay.value,
|
49
|
+
datetime.date(year=2024, month=6, day=10).strftime("%Y-%m-%d"): Holiday.dragonBoatFestival.value,
|
50
|
+
datetime.date(year=2024, month=9, day=15).strftime("%Y-%m-%d"): Holiday.midAutumnFestival.value,
|
51
|
+
datetime.date(year=2024, month=9, day=16).strftime("%Y-%m-%d"): Holiday.midAutumnFestival.value,
|
52
|
+
datetime.date(year=2024, month=9, day=17).strftime("%Y-%m-%d"): Holiday.midAutumnFestival.value,
|
53
|
+
datetime.date(year=2024, month=10, day=1).strftime("%Y-%m-%d"): Holiday.nationalDay.value,
|
54
|
+
datetime.date(year=2024, month=10, day=2).strftime("%Y-%m-%d"): Holiday.nationalDay.value,
|
55
|
+
datetime.date(year=2024, month=10, day=3).strftime("%Y-%m-%d"): Holiday.nationalDay.value,
|
56
|
+
datetime.date(year=2024, month=10, day=4).strftime("%Y-%m-%d"): Holiday.nationalDay.value,
|
57
|
+
datetime.date(year=2024, month=10, day=5).strftime("%Y-%m-%d"): Holiday.nationalDay.value,
|
58
|
+
datetime.date(year=2024, month=10, day=6).strftime("%Y-%m-%d"): Holiday.nationalDay.value,
|
59
|
+
datetime.date(year=2024, month=10, day=7).strftime("%Y-%m-%d"): Holiday.nationalDay.value,
|
60
|
+
}
|
61
|
+
|
62
|
+
workdayDict = {
|
63
|
+
# 2024年双休日调休
|
64
|
+
datetime.date(year=2024, month=2, day=4).strftime("%Y-%m-%d"): Holiday.springFestival.value,
|
65
|
+
datetime.date(year=2024, month=2, day=18).strftime("%Y-%m-%d"): Holiday.springFestival.value,
|
66
|
+
datetime.date(year=2024, month=4, day=7).strftime("%Y-%m-%d"): Holiday.tombSweepingDay.value,
|
67
|
+
datetime.date(year=2024, month=4, day=28).strftime("%Y-%m-%d"): Holiday.labourDay.value,
|
68
|
+
datetime.date(year=2024, month=5, day=11).strftime("%Y-%m-%d"): Holiday.labourDay.value,
|
69
|
+
datetime.date(year=2024, month=9, day=14).strftime("%Y-%m-%d"): Holiday.midAutumnFestival.value,
|
70
|
+
datetime.date(year=2024, month=9, day=29).strftime("%Y-%m-%d"): Holiday.nationalDay.value,
|
71
|
+
datetime.date(year=2024, month=10, day=12).strftime("%Y-%m-%d"): Holiday.nationalDay.value,
|
72
|
+
}
|
@@ -0,0 +1,182 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: jit-utils-backend
|
3
|
+
Version: 0.0.1
|
4
|
+
Summary: 极态后端工具包
|
5
|
+
Author: zangtao
|
6
|
+
Author-email: noguchisyou123456@gmail.com
|
7
|
+
Project-URL: Documentation, https://github.com/zangtao/jit-utils-backend
|
8
|
+
Project-URL: Source, https://github.com/zangtao/jit-utils-backend
|
9
|
+
Project-URL: Tracker, https://github.com/zangtao/jit-utils-backend/issues
|
10
|
+
Keywords: python,jit,sdk,apiAuth,utils,backend
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
12
|
+
Classifier: Intended Audience :: Developers
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
14
|
+
Classifier: Programming Language :: Python :: 3.6
|
15
|
+
Classifier: Programming Language :: Python :: 3.7
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
20
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
21
|
+
Classifier: Operating System :: Microsoft :: Windows
|
22
|
+
Classifier: Operating System :: POSIX :: Linux
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
24
|
+
Classifier: License :: OSI Approved :: MIT License
|
25
|
+
Requires-Python: >=3.6
|
26
|
+
Description-Content-Type: text/markdown
|
27
|
+
Requires-Dist: requests
|
28
|
+
Requires-Dist: qrcode
|
29
|
+
Requires-Dist: python-barcode
|
30
|
+
Requires-Dist: Pillow
|
31
|
+
|
32
|
+
# JIT Utils Backend
|
33
|
+
|
34
|
+
极态后端工具包 - 一个为后端开发提供便利工具的 Python 包。
|
35
|
+
|
36
|
+
## 安装
|
37
|
+
|
38
|
+
```bash
|
39
|
+
pip install jit-utils-backend
|
40
|
+
```
|
41
|
+
|
42
|
+
## 使用方法
|
43
|
+
|
44
|
+
### 导入包
|
45
|
+
|
46
|
+
```python
|
47
|
+
# 导入整个包
|
48
|
+
import jit_utils
|
49
|
+
|
50
|
+
# 导入特定功能
|
51
|
+
from jit_utils import now, randomString, Qrcode, Barcode
|
52
|
+
|
53
|
+
# 导入特定模块
|
54
|
+
from jit_utils import time_utils, string_utils
|
55
|
+
```
|
56
|
+
|
57
|
+
## 主要功能
|
58
|
+
|
59
|
+
### 1. 时间处理工具
|
60
|
+
|
61
|
+
```python
|
62
|
+
from jit_utils import now, today, dayShift, formatNow
|
63
|
+
|
64
|
+
# 获取当前时间
|
65
|
+
current_time = now()
|
66
|
+
|
67
|
+
# 获取今天的日期
|
68
|
+
today_date = today()
|
69
|
+
|
70
|
+
# 日期偏移
|
71
|
+
tomorrow = dayShift(today_date, 1)
|
72
|
+
|
73
|
+
# 格式化当前时间
|
74
|
+
formatted_time = formatNow("%Y-%m-%d %H:%M:%S")
|
75
|
+
```
|
76
|
+
|
77
|
+
### 2. 字符串处理工具
|
78
|
+
|
79
|
+
```python
|
80
|
+
from jit_utils import randomString, md5Str, getUuidStr
|
81
|
+
|
82
|
+
# 生成随机字符串
|
83
|
+
random_str = randomString(8)
|
84
|
+
|
85
|
+
# MD5 加密
|
86
|
+
encrypted = md5Str("hello world")
|
87
|
+
|
88
|
+
# 生成 UUID
|
89
|
+
uuid_str = getUuidStr()
|
90
|
+
```
|
91
|
+
|
92
|
+
### 3. 二维码生成
|
93
|
+
|
94
|
+
```python
|
95
|
+
from jit_utils import Qrcode
|
96
|
+
|
97
|
+
# 创建二维码
|
98
|
+
qr = Qrcode("https://example.com")
|
99
|
+
|
100
|
+
# 获取二维码图片的字节数据
|
101
|
+
qr_bytes = qr.toByte()
|
102
|
+
|
103
|
+
# 获取二维码的 base64 字符串
|
104
|
+
qr_str = qr.toStr()
|
105
|
+
```
|
106
|
+
|
107
|
+
### 4. 条形码生成
|
108
|
+
|
109
|
+
```python
|
110
|
+
from jit_utils import Barcode
|
111
|
+
|
112
|
+
# 创建条形码
|
113
|
+
barcode = Barcode("123456789")
|
114
|
+
|
115
|
+
# 获取条形码图片的字节数据
|
116
|
+
barcode_bytes = barcode.toByte()
|
117
|
+
|
118
|
+
# 获取条形码的 base64 字符串
|
119
|
+
barcode_str = barcode.toStr()
|
120
|
+
```
|
121
|
+
|
122
|
+
### 5. 数据验证
|
123
|
+
|
124
|
+
```python
|
125
|
+
from jit_utils import ParamsValidator
|
126
|
+
from dataclasses import dataclass
|
127
|
+
|
128
|
+
@dataclass
|
129
|
+
class UserParams(ParamsValidator):
|
130
|
+
name: str
|
131
|
+
age: int
|
132
|
+
email: str = ""
|
133
|
+
|
134
|
+
# 验证参数
|
135
|
+
params = UserParams("test_function", name="John", age=25)
|
136
|
+
```
|
137
|
+
|
138
|
+
### 6. 装饰器
|
139
|
+
|
140
|
+
```python
|
141
|
+
from jit_utils import forward
|
142
|
+
|
143
|
+
@forward("module.submodule")
|
144
|
+
def my_function():
|
145
|
+
pass
|
146
|
+
```
|
147
|
+
|
148
|
+
## 模块说明
|
149
|
+
|
150
|
+
- **time_utils**: 时间处理相关工具
|
151
|
+
- **string_utils**: 字符串处理相关工具
|
152
|
+
- **qrcode**: 二维码生成工具
|
153
|
+
- **barcode**: 条形码生成工具
|
154
|
+
- **validator**: 数据验证工具
|
155
|
+
- **network**: 网络相关工具
|
156
|
+
- **signature**: 签名相关工具
|
157
|
+
- **matchTool**: 匹配工具
|
158
|
+
- **clsTool**: 类工具
|
159
|
+
- **exceptions**: 异常处理
|
160
|
+
- **workday_constants**: 工作日常量
|
161
|
+
- **config**: 配置相关工具
|
162
|
+
|
163
|
+
## 依赖包
|
164
|
+
|
165
|
+
- requests
|
166
|
+
- qrcode
|
167
|
+
- python-barcode
|
168
|
+
- Pillow
|
169
|
+
- arrow
|
170
|
+
- python-dateutil
|
171
|
+
|
172
|
+
## 许可证
|
173
|
+
|
174
|
+
MIT License
|
175
|
+
|
176
|
+
## 作者
|
177
|
+
|
178
|
+
zangtao (noguchisyou123456@gmail.com)
|
179
|
+
|
180
|
+
## 版本
|
181
|
+
|
182
|
+
0.0.1
|
@@ -0,0 +1,32 @@
|
|
1
|
+
jit_utils/__init__.py,sha256=l1RBpnIRE1iEATvcgT6Trpbb6qG-3g6E87sK41i6nro,3050
|
2
|
+
jit_utils/apiAuthSign.py,sha256=TzYe3tDVQw0LYcE82IPcibtt_qyGTJ3XbWVjti5lGx0,2323
|
3
|
+
jit_utils/barcode.py,sha256=PuSHqxttr4rOGMAfojK7Ii72z4CoqxUQR_hmMOaElN8,1102
|
4
|
+
jit_utils/clsTool.py,sha256=tfMy3ITwfbfBLE6cjTrrRwMWB0aFh4fAYGJBZJ3vmCE,2316
|
5
|
+
jit_utils/convert.py,sha256=bIWM-W4rb9asAwH7I8wabe8GGd32JFhQaLSgD53Y14A,4726
|
6
|
+
jit_utils/decorator.py,sha256=_iuC7HYUlrEbzCpxdCFpgCCuMRgvT0l-1Xq0MxRcG2A,2149
|
7
|
+
jit_utils/exceptions.py,sha256=rr8bjOLkmGlaSVL9c2yyuZ1SRwuBU5mZJLg6Cdg5jbI,4457
|
8
|
+
jit_utils/forwarder.py,sha256=eaGPYliJV_2eXhSI5wmN5qOu3YLApbsKUIOQXXvj8c8,3603
|
9
|
+
jit_utils/matchTool.py,sha256=wjGfn8yykR8qEz0DNBos8ePFQEHwcunrPQ47DI4uS3Y,4304
|
10
|
+
jit_utils/network.py,sha256=XiFGsrf5f9iQkeiRuA8jgzWTcJpi8PhEnjdHTWqMIZE,700
|
11
|
+
jit_utils/qrcode.py,sha256=2skB8GORpZ6m3-KXZLyNwOnDTV-ARZqUQArizIOCAIo,1486
|
12
|
+
jit_utils/signature.py,sha256=OCw3OGKVw9IHtrFL3PvdL7wyyj0Q1RHz2nL_qnvf1R0,1649
|
13
|
+
jit_utils/spaceSender.py,sha256=uxM6Sqg6hTWGDX7DpBPaFGw7MHc_Ltq1xL3xkx2WhI4,1400
|
14
|
+
jit_utils/string.py,sha256=JrJD5lwQu5SDPnxANhQyfhzURCO7pXUzKzZlTf9hxTc,2543
|
15
|
+
jit_utils/time.py,sha256=miZ_EBp0v1aezMM6NMLA3gxEK7sTD90ER3cwtsgYb_Q,18601
|
16
|
+
jit_utils/validator.py,sha256=K_lWxVzs7ARy1aQ_IdVTDr0sLm7fOPQKKp1dr9T3pZA,984
|
17
|
+
jit_utils/workday_constants.py,sha256=53yxYAmTTlYx5TrmEO0oR-vHMgNV0pVubMUxxtGbmao,4235
|
18
|
+
jit_utils/config/__init__.py,sha256=-_pibLuJqcFEFJ2VzzW-vhxJx1ez0FsZaxNMQ4RzPTw,207
|
19
|
+
jit_utils/config/case.py,sha256=sFs5NvFaga7lbjlSDRwMKkufiIEYFSYSG3ha8PB1-58,2591
|
20
|
+
jit_utils/config/config.py,sha256=kH0u0eTwQR0shS0KwYd9f8c9uDxKPyjxYpYQ0rKZLXc,2713
|
21
|
+
jit_utils/config/exception.py,sha256=wrok-q14bTl8afClYgX649F2Qk0vrwl6LiWGgpkKDY0,378
|
22
|
+
jit_utils/config/field.py,sha256=5cq0M7zAtJrFkEHQ2H-1x95ypQxMyg07JjHnIAzSPQg,4759
|
23
|
+
tests/__init__.py,sha256=Feh5oxeLX-QAsWdK7XteVUZkQR1uZMfByvrB-Em0FEk,60
|
24
|
+
tests/run_tests.py,sha256=_0YG9MQCLkl18U-y-3BoI_KVbCZyGhMyPtLrOygAwVw,2959
|
25
|
+
tests/test_package_imports.py,sha256=gOn0H5LqxZ8B5jiNV23i9r2tZB4dJBEQf84V7LjVsq4,7704
|
26
|
+
tests/test_qrcode_barcode.py,sha256=RD08MCLHap0tb8hiXyrlkkdnK6t1Ij0p6gdCrJWqCIg,6598
|
27
|
+
tests/test_string_utils.py,sha256=i1Q98PwMrPbjc4nkb1O3Z4pwvu0SMZrSOYbgDdeU4D4,5845
|
28
|
+
tests/test_time_utils.py,sha256=nl9k_g0HmILHYTANMMRQgOF_vO4qGkfMzs6XiEJEnYA,6944
|
29
|
+
jit_utils_backend-0.0.1.dist-info/METADATA,sha256=IxlSo4XAQFTsE_yUsITSozIWWFqmSwLHTfqH1eDLpAE,3768
|
30
|
+
jit_utils_backend-0.0.1.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
31
|
+
jit_utils_backend-0.0.1.dist-info/top_level.txt,sha256=SvmeRMPwBF2UwUtkhHAzXWSPhwVATqN2FFmZp2pJHjA,16
|
32
|
+
jit_utils_backend-0.0.1.dist-info/RECORD,,
|
tests/__init__.py
ADDED
tests/run_tests.py
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
# -*-coding:utf-8-*-
|
3
|
+
"""
|
4
|
+
JIT Utils Backend 测试运行器
|
5
|
+
|
6
|
+
运行所有测试并生成报告
|
7
|
+
"""
|
8
|
+
import sys
|
9
|
+
import unittest
|
10
|
+
import os
|
11
|
+
|
12
|
+
# 添加项目根目录到Python路径
|
13
|
+
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
14
|
+
sys.path.insert(0, project_root)
|
15
|
+
|
16
|
+
|
17
|
+
def run_all_tests():
|
18
|
+
"""运行所有测试"""
|
19
|
+
# 发现测试目录中的所有测试
|
20
|
+
test_dir = os.path.dirname(os.path.abspath(__file__))
|
21
|
+
|
22
|
+
# 创建测试套件
|
23
|
+
loader = unittest.TestLoader()
|
24
|
+
suite = loader.discover(test_dir, pattern='test_*.py')
|
25
|
+
|
26
|
+
# 运行测试
|
27
|
+
runner = unittest.TextTestRunner(verbosity=2, stream=sys.stdout)
|
28
|
+
result = runner.run(suite)
|
29
|
+
|
30
|
+
# 打印总结
|
31
|
+
print("\n" + "="*60)
|
32
|
+
print("测试总结:")
|
33
|
+
print(f"运行测试数: {result.testsRun}")
|
34
|
+
print(f"失败数: {len(result.failures)}")
|
35
|
+
print(f"错误数: {len(result.errors)}")
|
36
|
+
print(f"跳过数: {len(result.skipped)}")
|
37
|
+
|
38
|
+
if result.failures:
|
39
|
+
print("\n失败的测试:")
|
40
|
+
for test, traceback in result.failures:
|
41
|
+
print(f" - {test}: {traceback.split('AssertionError:')[-1].strip()}")
|
42
|
+
|
43
|
+
if result.errors:
|
44
|
+
print("\n出错的测试:")
|
45
|
+
for test, traceback in result.errors:
|
46
|
+
print(f" - {test}: {traceback.split('Error:')[-1].strip()}")
|
47
|
+
|
48
|
+
if result.skipped:
|
49
|
+
print("\n跳过的测试:")
|
50
|
+
for test, reason in result.skipped:
|
51
|
+
print(f" - {test}: {reason}")
|
52
|
+
|
53
|
+
success_rate = ((result.testsRun - len(result.failures) - len(result.errors)) / result.testsRun * 100) if result.testsRun > 0 else 0
|
54
|
+
print(f"\n成功率: {success_rate:.1f}%")
|
55
|
+
|
56
|
+
return result.wasSuccessful()
|
57
|
+
|
58
|
+
|
59
|
+
def run_specific_test(test_name):
|
60
|
+
"""运行特定的测试模块"""
|
61
|
+
test_dir = os.path.dirname(os.path.abspath(__file__))
|
62
|
+
|
63
|
+
try:
|
64
|
+
# 动态导入测试模块
|
65
|
+
test_module = __import__(f'tests.{test_name}', fromlist=[test_name])
|
66
|
+
|
67
|
+
# 创建测试套件
|
68
|
+
loader = unittest.TestLoader()
|
69
|
+
suite = loader.loadTestsFromModule(test_module)
|
70
|
+
|
71
|
+
# 运行测试
|
72
|
+
runner = unittest.TextTestRunner(verbosity=2)
|
73
|
+
result = runner.run(suite)
|
74
|
+
|
75
|
+
return result.wasSuccessful()
|
76
|
+
|
77
|
+
except ImportError as e:
|
78
|
+
print(f"无法导入测试模块 '{test_name}': {e}")
|
79
|
+
return False
|
80
|
+
|
81
|
+
|
82
|
+
def main():
|
83
|
+
"""主函数"""
|
84
|
+
if len(sys.argv) > 1:
|
85
|
+
# 运行特定测试
|
86
|
+
test_name = sys.argv[1]
|
87
|
+
if not test_name.startswith('test_'):
|
88
|
+
test_name = f'test_{test_name}'
|
89
|
+
|
90
|
+
print(f"运行测试模块: {test_name}")
|
91
|
+
success = run_specific_test(test_name)
|
92
|
+
else:
|
93
|
+
# 运行所有测试
|
94
|
+
print("运行所有测试...")
|
95
|
+
success = run_all_tests()
|
96
|
+
|
97
|
+
# 根据测试结果设置退出码
|
98
|
+
sys.exit(0 if success else 1)
|
99
|
+
|
100
|
+
|
101
|
+
if __name__ == '__main__':
|
102
|
+
main()
|
@@ -0,0 +1,199 @@
|
|
1
|
+
# -*-coding:utf-8-*-
|
2
|
+
"""
|
3
|
+
测试包的导入功能
|
4
|
+
"""
|
5
|
+
import unittest
|
6
|
+
|
7
|
+
|
8
|
+
class TestPackageImports(unittest.TestCase):
|
9
|
+
"""包导入测试类"""
|
10
|
+
|
11
|
+
def test_main_package_import(self):
|
12
|
+
"""测试主包导入"""
|
13
|
+
try:
|
14
|
+
import jit_utils
|
15
|
+
self.assertTrue(hasattr(jit_utils, '__version__'))
|
16
|
+
self.assertTrue(hasattr(jit_utils, '__author__'))
|
17
|
+
self.assertEqual(jit_utils.__version__, '0.0.1')
|
18
|
+
self.assertEqual(jit_utils.__author__, 'zangtao')
|
19
|
+
except ImportError as e:
|
20
|
+
self.fail(f"主包导入失败: {e}")
|
21
|
+
|
22
|
+
def test_string_functions_import(self):
|
23
|
+
"""测试字符串函数导入"""
|
24
|
+
try:
|
25
|
+
from jit_utils import randomString, getUuidStr, md5Str
|
26
|
+
|
27
|
+
# 测试函数是否可调用
|
28
|
+
self.assertTrue(callable(randomString))
|
29
|
+
self.assertTrue(callable(getUuidStr))
|
30
|
+
self.assertTrue(callable(md5Str))
|
31
|
+
|
32
|
+
# 简单功能测试
|
33
|
+
random_str = randomString(6)
|
34
|
+
self.assertEqual(len(random_str), 6)
|
35
|
+
|
36
|
+
uuid_str = getUuidStr()
|
37
|
+
self.assertEqual(len(uuid_str), 32)
|
38
|
+
|
39
|
+
md5_hash = md5Str("test")
|
40
|
+
self.assertEqual(len(md5_hash), 32)
|
41
|
+
|
42
|
+
except ImportError as e:
|
43
|
+
self.fail(f"字符串函数导入失败: {e}")
|
44
|
+
|
45
|
+
def test_qrcode_barcode_import(self):
|
46
|
+
"""测试二维码和条形码类导入"""
|
47
|
+
try:
|
48
|
+
from jit_utils import Qrcode, Barcode
|
49
|
+
|
50
|
+
# 如果因为依赖问题导入为 None,跳过测试
|
51
|
+
if Qrcode is None or Barcode is None:
|
52
|
+
self.skipTest("二维码/条形码类因依赖问题不可用")
|
53
|
+
|
54
|
+
# 测试类是否可实例化
|
55
|
+
self.assertTrue(callable(Qrcode))
|
56
|
+
self.assertTrue(callable(Barcode))
|
57
|
+
|
58
|
+
# 创建实例
|
59
|
+
qr = Qrcode("test")
|
60
|
+
bc = Barcode("123456789")
|
61
|
+
|
62
|
+
self.assertEqual(qr.value, "test")
|
63
|
+
self.assertEqual(bc.value, "123456789")
|
64
|
+
|
65
|
+
except ImportError as e:
|
66
|
+
self.skipTest(f"二维码/条形码类导入失败(可能缺少依赖): {e}")
|
67
|
+
|
68
|
+
def test_module_imports(self):
|
69
|
+
"""测试模块级导入"""
|
70
|
+
try:
|
71
|
+
from jit_utils import string_utils
|
72
|
+
self.assertTrue(hasattr(string_utils, 'randomString'))
|
73
|
+
self.assertTrue(hasattr(string_utils, 'md5Str'))
|
74
|
+
except ImportError as e:
|
75
|
+
self.fail(f"string_utils 模块导入失败: {e}")
|
76
|
+
|
77
|
+
# 时间模块可能有依赖问题
|
78
|
+
try:
|
79
|
+
from jit_utils import time_utils
|
80
|
+
# 如果导入成功,测试一些基本属性
|
81
|
+
self.assertTrue(hasattr(time_utils, 'getTimestamp'))
|
82
|
+
except ImportError as e:
|
83
|
+
self.skipTest(f"time_utils 模块导入失败(可能缺少依赖): {e}")
|
84
|
+
|
85
|
+
def test_network_module_import(self):
|
86
|
+
"""测试网络模块导入"""
|
87
|
+
try:
|
88
|
+
from jit_utils import network
|
89
|
+
# 网络模块应该可以导入
|
90
|
+
self.assertIsNotNone(network)
|
91
|
+
except ImportError as e:
|
92
|
+
self.skipTest(f"network 模块导入失败: {e}")
|
93
|
+
|
94
|
+
def test_signature_module_import(self):
|
95
|
+
"""测试签名模块导入"""
|
96
|
+
try:
|
97
|
+
from jit_utils import signature
|
98
|
+
self.assertIsNotNone(signature)
|
99
|
+
except ImportError as e:
|
100
|
+
self.skipTest(f"signature 模块导入失败: {e}")
|
101
|
+
|
102
|
+
def test_validator_import(self):
|
103
|
+
"""测试验证器导入"""
|
104
|
+
try:
|
105
|
+
from jit_utils import ParamsValidator
|
106
|
+
if ParamsValidator is None:
|
107
|
+
self.skipTest("ParamsValidator 因依赖问题不可用")
|
108
|
+
self.assertTrue(callable(ParamsValidator))
|
109
|
+
except ImportError as e:
|
110
|
+
self.skipTest(f"ParamsValidator 导入失败(可能缺少依赖): {e}")
|
111
|
+
|
112
|
+
def test_exceptions_module_import(self):
|
113
|
+
"""测试异常模块导入"""
|
114
|
+
try:
|
115
|
+
from jit_utils import exceptions
|
116
|
+
self.assertIsNotNone(exceptions)
|
117
|
+
except ImportError as e:
|
118
|
+
self.skipTest(f"exceptions 模块导入失败(可能缺少依赖): {e}")
|
119
|
+
|
120
|
+
def test_config_module_import(self):
|
121
|
+
"""测试配置模块导入"""
|
122
|
+
try:
|
123
|
+
from jit_utils import config
|
124
|
+
self.assertIsNotNone(config)
|
125
|
+
except ImportError as e:
|
126
|
+
self.skipTest(f"config 模块导入失败(可能缺少依赖): {e}")
|
127
|
+
|
128
|
+
def test_workday_constants_import(self):
|
129
|
+
"""测试工作日常量导入"""
|
130
|
+
try:
|
131
|
+
from jit_utils import workday_constants
|
132
|
+
self.assertIsNotNone(workday_constants)
|
133
|
+
# 检查是否有工作日相关的常量
|
134
|
+
self.assertTrue(hasattr(workday_constants, 'holidayDict') or
|
135
|
+
hasattr(workday_constants, 'workdayDict'))
|
136
|
+
except ImportError as e:
|
137
|
+
self.skipTest(f"workday_constants 模块导入失败: {e}")
|
138
|
+
|
139
|
+
def test_decorator_import(self):
|
140
|
+
"""测试装饰器导入"""
|
141
|
+
try:
|
142
|
+
from jit_utils import forward
|
143
|
+
self.assertTrue(callable(forward))
|
144
|
+
except ImportError as e:
|
145
|
+
self.skipTest(f"forward 装饰器导入失败(可能缺少依赖): {e}")
|
146
|
+
|
147
|
+
def test_convert_classes_import(self):
|
148
|
+
"""测试转换器类导入"""
|
149
|
+
try:
|
150
|
+
from jit_utils import Converter, MemoryCompiler
|
151
|
+
if Converter is None or MemoryCompiler is None:
|
152
|
+
self.skipTest("转换器类因依赖问题不可用")
|
153
|
+
self.assertTrue(callable(Converter))
|
154
|
+
self.assertTrue(callable(MemoryCompiler))
|
155
|
+
except ImportError as e:
|
156
|
+
self.skipTest(f"转换器类导入失败(可能缺少依赖): {e}")
|
157
|
+
|
158
|
+
def test_all_exports(self):
|
159
|
+
"""测试 __all__ 导出列表"""
|
160
|
+
import jit_utils
|
161
|
+
|
162
|
+
# 检查 __all__ 是否存在
|
163
|
+
self.assertTrue(hasattr(jit_utils, '__all__'))
|
164
|
+
all_exports = jit_utils.__all__
|
165
|
+
self.assertIsInstance(all_exports, list)
|
166
|
+
self.assertGreater(len(all_exports), 0)
|
167
|
+
|
168
|
+
# 检查一些关键导出
|
169
|
+
expected_exports = [
|
170
|
+
'__version__', '__author__', 'randomString', 'md5Str',
|
171
|
+
'getUuidStr'
|
172
|
+
]
|
173
|
+
|
174
|
+
for export in expected_exports:
|
175
|
+
if export in all_exports:
|
176
|
+
self.assertTrue(hasattr(jit_utils, export), f"包中缺少导出: {export}")
|
177
|
+
|
178
|
+
# 检查可能为 None 的导出(因为依赖问题)
|
179
|
+
optional_exports = ['Qrcode', 'Barcode', 'ParamsValidator', 'Converter', 'MemoryCompiler']
|
180
|
+
for export in optional_exports:
|
181
|
+
if export in all_exports:
|
182
|
+
# 这些可能因为依赖问题为 None,只要存在就行
|
183
|
+
self.assertTrue(hasattr(jit_utils, export), f"包中缺少可选导出: {export}")
|
184
|
+
|
185
|
+
def test_star_import(self):
|
186
|
+
"""测试 from jit_utils import * 是否正常工作"""
|
187
|
+
# 由于 * 导入会污染命名空间,我们在这里只测试是否会出错
|
188
|
+
try:
|
189
|
+
exec("from jit_utils import *")
|
190
|
+
# 如果执行到这里说明没有导入错误
|
191
|
+
self.assertTrue(True)
|
192
|
+
except ImportError as e:
|
193
|
+
self.skipTest(f"星号导入失败(可能缺少依赖): {e}")
|
194
|
+
except Exception as e:
|
195
|
+
self.fail(f"星号导入出现意外错误: {e}")
|
196
|
+
|
197
|
+
|
198
|
+
if __name__ == '__main__':
|
199
|
+
unittest.main()
|