forked from JesperDramsch/python-deadlines
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_data_processing.py
More file actions
203 lines (161 loc) · 7.4 KB
/
Copy pathtest_data_processing.py
File metadata and controls
203 lines (161 loc) · 7.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
"""Tests for data processing and sorting functionality."""
# Add utils to path for imports
import sys
from datetime import datetime
from datetime import timezone
from pathlib import Path
import yaml
sys.path.append(str(Path(__file__).parent.parent / "utils"))
import sort_yaml
from tidy_conf.schema import Conference
class TestDataProcessing:
"""Test data processing functions."""
def test_sort_by_cfp(self, sample_conference):
"""Test sorting conferences by CFP deadline."""
conf = Conference(**sample_conference)
cfp_date = sort_yaml.sort_by_cfp(conf)
# The function does timezone conversion, so we check that it returns a valid datetime string
assert isinstance(cfp_date, str)
assert len(cfp_date) == 19 # YYYY-MM-DD HH:MM:SS format
assert cfp_date.startswith("2025-02")
def test_sort_by_date_passed(self, sample_conference):
"""Test identifying passed deadlines."""
# Future deadline
sample_conference["cfp"] = "2030-12-31 23:59:00"
conf = Conference(**sample_conference)
assert not sort_yaml.sort_by_date_passed(conf)
# Past deadline
sample_conference["cfp"] = "2020-01-01 00:00:00"
conf = Conference(**sample_conference)
assert sort_yaml.sort_by_date_passed(conf)
def test_sort_by_name(self, sample_conference):
"""Test sorting by conference name."""
conf = Conference(**sample_conference)
sort_key = sort_yaml.sort_by_name(conf)
expected = f"{conf.conference} {conf.year}".lower()
assert sort_key == expected
def test_order_keywords(self, sample_conference):
"""Test keyword ordering according to schema."""
# Test with dict input (which is the common case)
ordered_dict = sort_yaml.order_keywords(sample_conference)
# Should return a dict with ordered fields
assert isinstance(ordered_dict, dict)
assert ordered_dict["conference"] == sample_conference["conference"]
# Test that fields are ordered according to schema
schema_fields = ["conference", "year", "link", "cfp", "place", "start", "end", "sub"]
ordered_keys = list(ordered_dict.keys())
for field in schema_fields:
if field in sample_conference:
assert field in ordered_keys
def test_merge_duplicates(self):
"""Test duplicate conference merging."""
conferences = [
{
"conference": "PyCon Test",
"year": 2025,
"place": "Test City",
"link": "https://short.link",
"cfp": "2025-02-15 23:59:00",
"start": "2025-06-01",
"end": "2025-06-03",
"sub": "PY",
},
{
"conference": "PyCon Test",
"year": 2025,
"place": "Test City",
"link": "https://much-longer-and-more-detailed.link", # Longer link
"cfp": "2025-02-15 23:59:00",
"start": "2025-06-01",
"end": "2025-06-03",
"sub": "PY",
"sponsor": "https://sponsor.com", # Additional field
},
]
merged = sort_yaml.merge_duplicates(conferences)
# Should have only one conference after merging
assert len(merged) == 1
# Should keep the longer link and additional fields
merged_conf = merged[0]
assert merged_conf["link"] == "https://much-longer-and-more-detailed.link"
assert "sponsor" in merged_conf
def test_yaml_file_processing(self, temp_yaml_file, sample_conference):
"""Test processing YAML conference files."""
# Create test data
test_data = [sample_conference]
yaml_file_path = temp_yaml_file(test_data)
# Test loading
from pathlib import Path
yaml_path = Path(yaml_file_path)
with yaml_path.open(encoding="utf-8") as f:
loaded_data = yaml.safe_load(f)
assert len(loaded_data) == 1
assert loaded_data[0]["conference"] == "PyCon Test"
class TestDateHandling:
"""Test date parsing and timezone handling."""
def test_date_formats(self):
"""Test various date format parsing."""
valid_date_formats = ["2025-02-15 23:59:00", "2025-12-31 00:00:00", "2025-01-01 12:30:45"]
for date_str in valid_date_formats:
# Should not raise an exception
parsed_date = datetime.strptime(date_str, sort_yaml.DATEFORMAT).replace(tzinfo=timezone.utc)
assert isinstance(parsed_date, datetime)
def test_tba_words_handling(self):
"""Test handling of TBA/TBD words."""
tba_variations = ["tba", "tbd", "cancelled", "none", "na", "n/a", "nan", "n.a."]
for tba_word in tba_variations:
assert tba_word in sort_yaml.TBA_WORDS
def test_timezone_handling(self, sample_conference):
"""Test timezone field handling."""
# Test with timezone
sample_conference["timezone"] = "America/New_York"
conf = Conference(**sample_conference)
assert conf.timezone == "America/New_York"
# Test without timezone (should be None/default to AoE)
sample_conference["timezone"] = None
conf = Conference(**sample_conference)
assert conf.timezone is None
class TestDataIntegrity:
"""Test data integrity and consistency."""
def test_conference_data_consistency(self, sample_conference):
"""Test that conference data maintains consistency."""
conf = Conference(**sample_conference)
# Basic consistency checks
assert conf.start <= conf.end
assert conf.year >= 1989
assert conf.conference.strip() != ""
assert conf.place.strip() != ""
def test_required_fields_completeness(self, sample_conference):
"""Test that all required fields are present and valid."""
conf = Conference(**sample_conference)
required_fields = ["conference", "year", "link", "cfp", "place", "start", "end", "sub"]
for field in required_fields:
assert hasattr(conf, field)
value = getattr(conf, field)
assert value is not None
if isinstance(value, str):
assert value.strip() != ""
def test_url_accessibility_format(self, sample_conference):
"""Test URL format for accessibility."""
# Test various valid URL formats
valid_urls = [
"https://example.com",
"https://sub.example.com/path",
"https://example.com/path?param=value",
"https://example.org/path#section",
]
for url in valid_urls:
sample_conference["link"] = url
conf = Conference(**sample_conference)
assert str(conf.link).startswith(("http://", "https://"))
def test_date_logic_validation(self, sample_conference):
"""Test logical date relationships."""
# CFP should typically be before conference start
from datetime import datetime
# In most cases, CFP should be before the conference
# (Though not enforced as a hard rule since there might be exceptions)
cfp_date = datetime.strptime(sample_conference["cfp"], "%Y-%m-%d %H:%M:%S").replace(tzinfo=timezone.utc)
start_date = sample_conference["start"]
# Ensure both dates exist for logical validation
assert cfp_date is not None
assert start_date is not None