Skip to content

Commit 314f293

Browse files
Merge pull request #6 from FengzihangCode/main
更新包
2 parents 8151870 + 9bdbd8f commit 314f293

File tree

7 files changed

+74
-13
lines changed

7 files changed

+74
-13
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "usf"
7-
version = "0.1.2"
7+
version = "0.2.0"
88
description = "A lightweight Universal Schedule Format (USF) parser and generator."
99
authors = [{ name = "USF-org", email = "USF-org@outlook.com" }]
1010
license = { text = "MIT" }

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
jsonschema==4.0.0

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
setup(
44
name="usf",
5-
version="0.1.2",
5+
version="0.2.0",
66
packages=find_packages(),
77
install_requires=[],
88
python_requires=">=3.6",

tests/test_usf.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def setUp(self):
2222
self.generator.add_schedule(1, "all", "Physics", 2) # 星期一,第二节,物理
2323

2424
# 生成 USF 数据
25-
self.usf_data = self.generator.generate_usf_data()
25+
self.usf_data = self.generator.generate()
2626

2727
def test_usf_generation(self):
2828
"""测试 USF 生成"""
@@ -38,7 +38,10 @@ def test_usf_generation(self):
3838

3939
def test_usf_parser(self):
4040
"""测试 USF 解析"""
41+
# 将生成的 USF 数据转为 JSON 字符串
4142
json_data = json.dumps(self.usf_data, indent=2)
43+
44+
# 使用解析器解析数据
4245
parser = USFParser(json_data)
4346

4447
self.assertEqual(len(parser.get_subjects()), 2)
@@ -63,7 +66,38 @@ def test_usf_validation(self):
6366
"subjects": self.usf_data["subjects"],
6467
"periods": self.usf_data["periods"]
6568
}
66-
self.assertFalse(validator.validate(invalid_data))
69+
70+
# 这里我们添加了额外的错误处理来捕获无效数据的校验错误
71+
with self.assertRaises(jsonschema.exceptions.ValidationError):
72+
validator.validate(invalid_data)
73+
74+
def test_invalid_period(self):
75+
"""测试无效时间段"""
76+
invalid_periods_data = {
77+
"version": 1,
78+
"subjects": self.usf_data["subjects"],
79+
"periods": [["invalid", "format"]],
80+
"timetable": self.usf_data["timetable"]
81+
}
82+
83+
# 使用校验器验证无效的时间段数据
84+
validator = USFValidator()
85+
with self.assertRaises(jsonschema.exceptions.ValidationError):
86+
validator.validate(invalid_periods_data)
87+
88+
def test_invalid_subject(self):
89+
"""测试无效科目"""
90+
invalid_subjects_data = {
91+
"version": 1,
92+
"subjects": {"InvalidSubject": {}},
93+
"periods": self.usf_data["periods"],
94+
"timetable": self.usf_data["timetable"]
95+
}
96+
97+
# 使用校验器验证无效的科目数据
98+
validator = USFValidator()
99+
with self.assertRaises(jsonschema.exceptions.ValidationError):
100+
validator.validate(invalid_subjects_data)
67101

68102
if __name__ == "__main__":
69103
unittest.main()

usf/generator.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
import re
23

34
class USFGenerator:
45
def __init__(self, version=1):
@@ -23,6 +24,9 @@ def add_subject(self, name, simplified_name=None, teacher=None, room=None):
2324
teacher (str, optional): Teacher's name.
2425
room (str, optional): Classroom.
2526
"""
27+
if name in self.subjects:
28+
raise ValueError(f"Subject '{name}' already exists.")
29+
2630
self.subjects[name] = {
2731
"simplified_name": simplified_name or name,
2832
"teacher": teacher or "",
@@ -40,6 +44,10 @@ def add_period(self, start_time, end_time):
4044
Returns:
4145
int: Index of the added period (1-based).
4246
"""
47+
time_pattern = "^(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d$"
48+
if not re.match(time_pattern, start_time) or not re.match(time_pattern, end_time):
49+
raise ValueError(f"Invalid time format. Must be 'HH:MM:SS'.")
50+
4351
self.periods.append([start_time, end_time])
4452
return len(self.periods) # Return 1-based index
4553

@@ -57,6 +65,9 @@ def add_schedule(self, day, week_type, subject, period_index):
5765
raise ValueError(f"Subject '{subject}' is not defined.")
5866
if period_index < 1 or period_index > len(self.periods):
5967
raise ValueError(f"Invalid period index {period_index}.")
68+
if week_type not in ["all", "even", "odd"]:
69+
raise ValueError(f"Invalid week type '{week_type}'. Must be 'all', 'even', or 'odd'.")
70+
6071
self.timetable.append([day, week_type, subject, period_index])
6172

6273
def generate(self):
@@ -80,5 +91,8 @@ def save_to_file(self, filename):
8091
Args:
8192
filename (str): Output filename.
8293
"""
83-
with open(filename, "w", encoding="utf-8") as f:
84-
json.dump(self.generate(), f, indent=2, ensure_ascii=False)
94+
try:
95+
with open(filename, "w", encoding="utf-8") as f:
96+
json.dump(self.generate(), f, indent=2, ensure_ascii=False)
97+
except Exception as e:
98+
raise IOError(f"Failed to save USF data to {filename}: {e}")

usf/parser.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,13 @@ def __init__(self, filename):
88
Args:
99
filename (str): Path to USF JSON file.
1010
"""
11-
with open(filename, "r", encoding="utf-8") as f:
12-
self.data = json.load(f)
11+
try:
12+
with open(filename, "r", encoding="utf-8") as f:
13+
self.data = json.load(f)
14+
except FileNotFoundError:
15+
raise FileNotFoundError(f"File '{filename}' not found.")
16+
except json.JSONDecodeError:
17+
raise ValueError(f"Failed to decode JSON from the file '{filename}'.")
1318

1419
def get_subjects(self):
1520
"""Return the subjects dictionary."""

usf/validator.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,13 @@ def __init__(self, schema_file="schema.json"):
1010
Args:
1111
schema_file (str, optional): Path to JSON Schema. Defaults to "schema.json".
1212
"""
13-
with open(schema_file, "r", encoding="utf-8") as f:
14-
self.schema = json.load(f)
13+
try:
14+
with open(schema_file, "r", encoding="utf-8") as f:
15+
self.schema = json.load(f)
16+
except FileNotFoundError:
17+
raise FileNotFoundError(f"Schema file '{schema_file}' not found.")
18+
except json.JSONDecodeError:
19+
raise ValueError(f"Failed to decode JSON from the schema file '{schema_file}'.")
1520

1621
def validate(self, data):
1722
"""
@@ -23,6 +28,8 @@ def validate(self, data):
2328
Returns:
2429
bool: True if valid, raises an error if invalid.
2530
"""
26-
validate(instance=data, schema=self.schema)
27-
return True
28-
31+
try:
32+
validate(instance=data, schema=self.schema)
33+
except jsonschema.exceptions.ValidationError as e:
34+
raise ValueError(f"USF data validation failed: {e.message}")
35+
return True

0 commit comments

Comments
 (0)