staran 1.0.0__py3-none-any.whl → 1.0.3__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.
@@ -0,0 +1,519 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ Date类核心功能测试
6
+ ================
7
+
8
+ 测试Date类的所有功能,包括:
9
+ - 对象创建和初始化
10
+ - 格式记忆和保持
11
+ - 日期运算
12
+ - 格式化输出
13
+ - 比较操作
14
+ - 错误处理
15
+ - API命名规范
16
+ - 向后兼容性
17
+ """
18
+
19
+ import unittest
20
+ import datetime
21
+ import sys
22
+ import os
23
+
24
+ # 添加项目根目录到路径
25
+ sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..'))
26
+
27
+ from staran.date.core import Date
28
+
29
+
30
+ class TestDateCreation(unittest.TestCase):
31
+ """测试Date对象创建"""
32
+
33
+ def test_create_from_string_yyyy(self):
34
+ """测试从YYYY字符串创建"""
35
+ d = Date('2025')
36
+ self.assertEqual(d.year, 2025)
37
+ self.assertEqual(d.month, 1)
38
+ self.assertEqual(d.day, 1)
39
+ self.assertEqual(str(d), '2025')
40
+
41
+ def test_create_from_string_yyyymm(self):
42
+ """测试从YYYYMM字符串创建"""
43
+ d = Date('202504')
44
+ self.assertEqual(d.year, 2025)
45
+ self.assertEqual(d.month, 4)
46
+ self.assertEqual(d.day, 1)
47
+ self.assertEqual(str(d), '202504')
48
+
49
+ def test_create_from_string_yyyymmdd(self):
50
+ """测试从YYYYMMDD字符串创建"""
51
+ d = Date('20250415')
52
+ self.assertEqual(d.year, 2025)
53
+ self.assertEqual(d.month, 4)
54
+ self.assertEqual(d.day, 15)
55
+ self.assertEqual(str(d), '20250415')
56
+
57
+ def test_create_from_position_args(self):
58
+ """测试从位置参数创建"""
59
+ d = Date(2025, 4, 15)
60
+ self.assertEqual(d.year, 2025)
61
+ self.assertEqual(d.month, 4)
62
+ self.assertEqual(d.day, 15)
63
+ self.assertEqual(str(d), '2025-04-15')
64
+
65
+ def test_create_from_keyword_args(self):
66
+ """测试从关键字参数创建"""
67
+ d = Date(year=2025, month=4, day=15)
68
+ self.assertEqual(d.year, 2025)
69
+ self.assertEqual(d.month, 4)
70
+ self.assertEqual(d.day, 15)
71
+
72
+ def test_create_from_datetime_object(self):
73
+ """测试从datetime.datetime对象创建"""
74
+ dt = datetime.datetime(2025, 4, 15, 10, 30)
75
+ d = Date(dt)
76
+ self.assertEqual(d.year, 2025)
77
+ self.assertEqual(d.month, 4)
78
+ self.assertEqual(d.day, 15)
79
+
80
+ def test_create_from_date_object(self):
81
+ """测试从datetime.date对象创建"""
82
+ dt = datetime.date(2025, 4, 15)
83
+ d = Date(dt)
84
+ self.assertEqual(d.year, 2025)
85
+ self.assertEqual(d.month, 4)
86
+ self.assertEqual(d.day, 15)
87
+
88
+ def test_create_today(self):
89
+ """测试创建今日对象"""
90
+ d = Date()
91
+ today = datetime.date.today()
92
+ self.assertEqual(d.year, today.year)
93
+ self.assertEqual(d.month, today.month)
94
+ self.assertEqual(d.day, today.day)
95
+
96
+
97
+ class TestDateClassMethods(unittest.TestCase):
98
+ """测试Date类方法"""
99
+
100
+ def test_from_string(self):
101
+ """测试from_string类方法"""
102
+ d = Date.from_string('20250415')
103
+ self.assertEqual(d.year, 2025)
104
+ self.assertEqual(d.month, 4)
105
+ self.assertEqual(d.day, 15)
106
+
107
+ def test_from_timestamp(self):
108
+ """测试from_timestamp类方法"""
109
+ timestamp = datetime.datetime(2025, 4, 15).timestamp()
110
+ d = Date.from_timestamp(timestamp)
111
+ self.assertEqual(d.year, 2025)
112
+ self.assertEqual(d.month, 4)
113
+ self.assertEqual(d.day, 15)
114
+
115
+ def test_from_date_object(self):
116
+ """测试from_date_object类方法"""
117
+ date_obj = datetime.date(2025, 4, 15)
118
+ d = Date.from_date_object(date_obj)
119
+ self.assertEqual(d.year, 2025)
120
+ self.assertEqual(d.month, 4)
121
+ self.assertEqual(d.day, 15)
122
+
123
+ def test_today(self):
124
+ """测试today类方法"""
125
+ d = Date.today()
126
+ today = datetime.date.today()
127
+ self.assertEqual(d.year, today.year)
128
+ self.assertEqual(d.month, today.month)
129
+ self.assertEqual(d.day, today.day)
130
+
131
+
132
+ class TestDateFormatting(unittest.TestCase):
133
+ """测试日期格式化"""
134
+
135
+ def setUp(self):
136
+ self.date = Date('20250415')
137
+
138
+ def test_format_default(self):
139
+ """测试format_default方法"""
140
+ self.assertEqual(self.date.format_default(), '20250415')
141
+
142
+ def test_format_iso(self):
143
+ """测试format_iso方法"""
144
+ self.assertEqual(self.date.format_iso(), '2025-04-15')
145
+
146
+ def test_format_chinese(self):
147
+ """测试format_chinese方法"""
148
+ self.assertEqual(self.date.format_chinese(), '2025年04月15日')
149
+
150
+ def test_format_compact(self):
151
+ """测试format_compact方法"""
152
+ self.assertEqual(self.date.format_compact(), '20250415')
153
+
154
+ def test_format_slash(self):
155
+ """测试format_slash方法"""
156
+ self.assertEqual(self.date.format_slash(), '2025/04/15')
157
+
158
+ def test_format_dot(self):
159
+ """测试format_dot方法"""
160
+ self.assertEqual(self.date.format_dot(), '2025.04.15')
161
+
162
+ def test_format_year_month(self):
163
+ """测试format_year_month方法"""
164
+ self.assertEqual(self.date.format_year_month(), '2025-04')
165
+
166
+ def test_format_year_month_compact(self):
167
+ """测试format_year_month_compact方法"""
168
+ self.assertEqual(self.date.format_year_month_compact(), '202504')
169
+
170
+ def test_format_custom(self):
171
+ """测试format_custom方法"""
172
+ self.assertEqual(self.date.format_custom('%Y年%m月'), '2025年04月')
173
+
174
+
175
+ class TestDateArithmetic(unittest.TestCase):
176
+ """测试日期运算"""
177
+
178
+ def test_add_days(self):
179
+ """测试add_days方法"""
180
+ date = Date('20250415')
181
+ new_date = date.add_days(10)
182
+ self.assertEqual(str(new_date), '20250425')
183
+
184
+ def test_add_months(self):
185
+ """测试add_months方法"""
186
+ date = Date('202504')
187
+ new_date = date.add_months(2)
188
+ self.assertEqual(str(new_date), '202506')
189
+
190
+ def test_add_years(self):
191
+ """测试add_years方法"""
192
+ date = Date('2025')
193
+ new_date = date.add_years(1)
194
+ self.assertEqual(str(new_date), '2026')
195
+
196
+ def test_subtract_days(self):
197
+ """测试subtract_days方法"""
198
+ date = Date('20250415')
199
+ new_date = date.subtract_days(5)
200
+ self.assertEqual(str(new_date), '20250410')
201
+
202
+ def test_subtract_months(self):
203
+ """测试subtract_months方法"""
204
+ date = Date('202504')
205
+ new_date = date.subtract_months(1)
206
+ self.assertEqual(str(new_date), '202503')
207
+
208
+ def test_subtract_years(self):
209
+ """测试subtract_years方法"""
210
+ date = Date('2025')
211
+ new_date = date.subtract_years(1)
212
+ self.assertEqual(str(new_date), '2024')
213
+
214
+ def test_format_preservation(self):
215
+ """测试运算后格式保持"""
216
+ # 年份格式
217
+ year_date = Date('2025')
218
+ self.assertEqual(str(year_date.add_years(1)), '2026')
219
+
220
+ # 年月格式
221
+ ym_date = Date('202504')
222
+ self.assertEqual(str(ym_date.add_months(1)), '202505')
223
+
224
+ # 完整格式
225
+ full_date = Date('20250415')
226
+ self.assertEqual(str(full_date.add_days(1)), '20250416')
227
+
228
+
229
+ class TestDateComparison(unittest.TestCase):
230
+ """测试日期比较"""
231
+
232
+ def test_equality(self):
233
+ """测试相等比较"""
234
+ date1 = Date('20250415')
235
+ date2 = Date('20250415')
236
+ date3 = Date('20250416')
237
+
238
+ self.assertEqual(date1, date2)
239
+ self.assertNotEqual(date1, date3)
240
+
241
+ def test_less_than(self):
242
+ """测试小于比较"""
243
+ date1 = Date('20250415')
244
+ date2 = Date('20250416')
245
+
246
+ self.assertLess(date1, date2)
247
+ self.assertFalse(date2 < date1)
248
+
249
+ def test_greater_than(self):
250
+ """测试大于比较"""
251
+ date1 = Date('20250415')
252
+ date2 = Date('20250416')
253
+
254
+ self.assertGreater(date2, date1)
255
+ self.assertFalse(date1 > date2)
256
+
257
+ def test_less_equal(self):
258
+ """测试小于等于比较"""
259
+ date1 = Date('20250415')
260
+ date2 = Date('20250415')
261
+ date3 = Date('20250416')
262
+
263
+ self.assertLessEqual(date1, date2)
264
+ self.assertLessEqual(date1, date3)
265
+
266
+ def test_greater_equal(self):
267
+ """测试大于等于比较"""
268
+ date1 = Date('20250415')
269
+ date2 = Date('20250415')
270
+ date3 = Date('20250414')
271
+
272
+ self.assertGreaterEqual(date1, date2)
273
+ self.assertGreaterEqual(date1, date3)
274
+
275
+ def test_hash(self):
276
+ """测试哈希值"""
277
+ date1 = Date('20250415')
278
+ date2 = Date('20250415')
279
+
280
+ self.assertEqual(hash(date1), hash(date2))
281
+
282
+
283
+ class TestDateGetters(unittest.TestCase):
284
+ """测试获取方法"""
285
+
286
+ def setUp(self):
287
+ self.date = Date('20250415') # 2025年4月15日,星期二
288
+
289
+ def test_get_weekday(self):
290
+ """测试get_weekday方法"""
291
+ weekday = self.date.get_weekday()
292
+ self.assertEqual(weekday, 1) # 星期二 = 1
293
+
294
+ def test_get_isoweekday(self):
295
+ """测试get_isoweekday方法"""
296
+ isoweekday = self.date.get_isoweekday()
297
+ self.assertEqual(isoweekday, 2) # 星期二 = 2
298
+
299
+ def test_get_month_start(self):
300
+ """测试get_month_start方法"""
301
+ month_start = self.date.get_month_start()
302
+ self.assertEqual(str(month_start), '20250401')
303
+
304
+ def test_get_month_end(self):
305
+ """测试get_month_end方法"""
306
+ month_end = self.date.get_month_end()
307
+ self.assertEqual(str(month_end), '20250430')
308
+
309
+ def test_get_year_start(self):
310
+ """测试get_year_start方法"""
311
+ year_start = self.date.get_year_start()
312
+ self.assertEqual(str(year_start), '20250101')
313
+
314
+ def test_get_year_end(self):
315
+ """测试get_year_end方法"""
316
+ year_end = self.date.get_year_end()
317
+ self.assertEqual(str(year_end), '20251231')
318
+
319
+ def test_get_days_in_month(self):
320
+ """测试get_days_in_month方法"""
321
+ days = self.date.get_days_in_month()
322
+ self.assertEqual(days, 30) # 4月有30天
323
+
324
+ def test_get_days_in_year(self):
325
+ """测试get_days_in_year方法"""
326
+ days = self.date.get_days_in_year()
327
+ self.assertEqual(days, 365) # 2025年不是闰年
328
+
329
+
330
+ class TestDatePredicates(unittest.TestCase):
331
+ """测试判断方法"""
332
+
333
+ def setUp(self):
334
+ self.date = Date('20250415') # 2025年4月15日,星期二
335
+
336
+ def test_is_weekend(self):
337
+ """测试is_weekend方法"""
338
+ self.assertFalse(self.date.is_weekend()) # 星期二不是周末
339
+
340
+ # 测试周末
341
+ saturday = Date('20250419') # 星期六
342
+ self.assertTrue(saturday.is_weekend())
343
+
344
+ def test_is_weekday(self):
345
+ """测试is_weekday方法"""
346
+ self.assertTrue(self.date.is_weekday()) # 星期二是工作日
347
+
348
+ # 测试周末
349
+ sunday = Date('20250420') # 星期日
350
+ self.assertFalse(sunday.is_weekday())
351
+
352
+ def test_is_leap_year(self):
353
+ """测试is_leap_year方法"""
354
+ self.assertFalse(self.date.is_leap_year()) # 2025不是闰年
355
+
356
+ # 测试闰年
357
+ leap_year_date = Date('20240229') # 2024是闰年
358
+ self.assertTrue(leap_year_date.is_leap_year())
359
+
360
+ def test_is_month_start(self):
361
+ """测试is_month_start方法"""
362
+ self.assertFalse(self.date.is_month_start()) # 15号不是月初
363
+
364
+ # 测试月初
365
+ month_start = Date('20250401')
366
+ self.assertTrue(month_start.is_month_start())
367
+
368
+ def test_is_month_end(self):
369
+ """测试is_month_end方法"""
370
+ self.assertFalse(self.date.is_month_end()) # 15号不是月末
371
+
372
+ # 测试月末
373
+ month_end = Date('20250430')
374
+ self.assertTrue(month_end.is_month_end())
375
+
376
+ def test_is_year_start(self):
377
+ """测试is_year_start方法"""
378
+ self.assertFalse(self.date.is_year_start()) # 4月15日不是年初
379
+
380
+ # 测试年初
381
+ year_start = Date('20250101')
382
+ self.assertTrue(year_start.is_year_start())
383
+
384
+ def test_is_year_end(self):
385
+ """测试is_year_end方法"""
386
+ self.assertFalse(self.date.is_year_end()) # 4月15日不是年末
387
+
388
+ # 测试年末
389
+ year_end = Date('20251231')
390
+ self.assertTrue(year_end.is_year_end())
391
+
392
+
393
+ class TestDateConversion(unittest.TestCase):
394
+ """测试转换方法"""
395
+
396
+ def setUp(self):
397
+ self.date = Date('20250415')
398
+
399
+ def test_to_tuple(self):
400
+ """测试to_tuple方法"""
401
+ result = self.date.to_tuple()
402
+ self.assertEqual(result, (2025, 4, 15))
403
+
404
+ def test_to_dict(self):
405
+ """测试to_dict方法"""
406
+ result = self.date.to_dict()
407
+ expected = {'year': 2025, 'month': 4, 'day': 15}
408
+ self.assertEqual(result, expected)
409
+
410
+ def test_to_date_object(self):
411
+ """测试to_date_object方法"""
412
+ result = self.date.to_date_object()
413
+ expected = datetime.date(2025, 4, 15)
414
+ self.assertEqual(result, expected)
415
+
416
+ def test_to_datetime_object(self):
417
+ """测试to_datetime_object方法"""
418
+ result = self.date.to_datetime_object()
419
+ expected = datetime.datetime(2025, 4, 15)
420
+ self.assertEqual(result, expected)
421
+
422
+ def test_to_timestamp(self):
423
+ """测试to_timestamp方法"""
424
+ result = self.date.to_timestamp()
425
+ self.assertIsInstance(result, float)
426
+
427
+
428
+ class TestDateCalculation(unittest.TestCase):
429
+ """测试计算方法"""
430
+
431
+ def test_calculate_difference_days(self):
432
+ """测试calculate_difference_days方法"""
433
+ date1 = Date('20250415')
434
+ date2 = Date('20250425')
435
+
436
+ diff = date1.calculate_difference_days(date2)
437
+ self.assertEqual(diff, 10)
438
+
439
+ # 反向计算
440
+ diff_reverse = date2.calculate_difference_days(date1)
441
+ self.assertEqual(diff_reverse, -10)
442
+
443
+ def test_calculate_difference_months(self):
444
+ """测试calculate_difference_months方法"""
445
+ date1 = Date('20250415')
446
+ date2 = Date('20250615')
447
+
448
+ diff = date1.calculate_difference_months(date2)
449
+ self.assertEqual(diff, 2)
450
+
451
+
452
+ class TestBackwardCompatibility(unittest.TestCase):
453
+ """测试向后兼容性"""
454
+
455
+ def setUp(self):
456
+ self.date = Date('20250415')
457
+
458
+ def test_old_format_method(self):
459
+ """测试旧的format方法"""
460
+ result = self.date.format('%Y年%m月')
461
+ self.assertEqual(result, '2025年04月')
462
+
463
+ def test_old_to_date_method(self):
464
+ """测试旧的to_date方法"""
465
+ result = self.date.to_date()
466
+ expected = datetime.date(2025, 4, 15)
467
+ self.assertEqual(result, expected)
468
+
469
+ def test_old_to_datetime_method(self):
470
+ """测试旧的to_datetime方法"""
471
+ result = self.date.to_datetime()
472
+ expected = datetime.datetime(2025, 4, 15)
473
+ self.assertEqual(result, expected)
474
+
475
+ def test_old_weekday_method(self):
476
+ """测试旧的weekday方法"""
477
+ result = self.date.weekday()
478
+ self.assertEqual(result, 1) # 星期二
479
+
480
+ def test_old_difference_method(self):
481
+ """测试旧的difference方法"""
482
+ other_date = Date('20250425')
483
+ diff = self.date.difference(other_date)
484
+ self.assertEqual(diff, 10)
485
+
486
+
487
+ class TestDateErrorHandling(unittest.TestCase):
488
+ """测试错误处理"""
489
+
490
+ def test_invalid_string_format(self):
491
+ """测试无效字符串格式"""
492
+ with self.assertRaises(ValueError):
493
+ Date('invalid')
494
+
495
+ with self.assertRaises(ValueError):
496
+ Date('20251') # 5位数字
497
+
498
+ def test_invalid_date_values(self):
499
+ """测试无效日期值"""
500
+ with self.assertRaises(ValueError):
501
+ Date('20250230') # 2月30日不存在
502
+
503
+ with self.assertRaises(ValueError):
504
+ Date(2025, 13, 1) # 13月不存在
505
+
506
+ with self.assertRaises(ValueError):
507
+ Date(2025, 4, 31) # 4月31日不存在
508
+
509
+ def test_invalid_argument_types(self):
510
+ """测试无效参数类型"""
511
+ with self.assertRaises(TypeError):
512
+ Date([2025, 4, 15]) # 列表不支持
513
+
514
+ with self.assertRaises(TypeError):
515
+ Date({'year': 2025}) # 字典不支持
516
+
517
+
518
+ if __name__ == '__main__':
519
+ unittest.main(verbosity=2)
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ """
5
+ Staran 工具模块
6
+ =============
7
+
8
+ 提供辅助功能和工具函数。
9
+ """
10
+
11
+ __all__ = []