fishertools 0.2.1__py3-none-any.whl → 0.4.0__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.
- fishertools/__init__.py +16 -5
- fishertools/errors/__init__.py +11 -3
- fishertools/errors/exception_types.py +282 -0
- fishertools/errors/explainer.py +87 -1
- fishertools/errors/models.py +73 -1
- fishertools/errors/patterns.py +40 -0
- fishertools/examples/cli_example.py +156 -0
- fishertools/examples/learn_example.py +65 -0
- fishertools/examples/logger_example.py +176 -0
- fishertools/examples/menu_example.py +101 -0
- fishertools/examples/storage_example.py +175 -0
- fishertools/input_utils.py +185 -0
- fishertools/learn/__init__.py +19 -2
- fishertools/learn/examples.py +88 -1
- fishertools/learn/knowledge_engine.py +321 -0
- fishertools/learn/repl/__init__.py +19 -0
- fishertools/learn/repl/cli.py +31 -0
- fishertools/learn/repl/code_sandbox.py +229 -0
- fishertools/learn/repl/command_handler.py +544 -0
- fishertools/learn/repl/command_parser.py +165 -0
- fishertools/learn/repl/engine.py +479 -0
- fishertools/learn/repl/models.py +121 -0
- fishertools/learn/repl/session_manager.py +284 -0
- fishertools/learn/repl/test_code_sandbox.py +261 -0
- fishertools/learn/repl/test_code_sandbox_pbt.py +148 -0
- fishertools/learn/repl/test_command_handler.py +224 -0
- fishertools/learn/repl/test_command_handler_pbt.py +189 -0
- fishertools/learn/repl/test_command_parser.py +160 -0
- fishertools/learn/repl/test_command_parser_pbt.py +100 -0
- fishertools/learn/repl/test_engine.py +190 -0
- fishertools/learn/repl/test_session_manager.py +310 -0
- fishertools/learn/repl/test_session_manager_pbt.py +182 -0
- fishertools/learn/test_knowledge_engine.py +241 -0
- fishertools/learn/test_knowledge_engine_pbt.py +180 -0
- fishertools/patterns/__init__.py +46 -0
- fishertools/patterns/cli.py +175 -0
- fishertools/patterns/logger.py +140 -0
- fishertools/patterns/menu.py +99 -0
- fishertools/patterns/storage.py +127 -0
- fishertools/readme_transformer.py +631 -0
- fishertools/safe/__init__.py +6 -1
- fishertools/safe/files.py +329 -1
- fishertools/transform_readme.py +105 -0
- fishertools-0.4.0.dist-info/METADATA +104 -0
- fishertools-0.4.0.dist-info/RECORD +131 -0
- {fishertools-0.2.1.dist-info → fishertools-0.4.0.dist-info}/WHEEL +1 -1
- tests/test_documentation_properties.py +329 -0
- tests/test_documentation_structure.py +349 -0
- tests/test_errors/test_exception_types.py +446 -0
- tests/test_errors/test_exception_types_pbt.py +333 -0
- tests/test_errors/test_patterns.py +52 -0
- tests/test_input_utils/__init__.py +1 -0
- tests/test_input_utils/test_input_utils.py +65 -0
- tests/test_learn/test_examples.py +179 -1
- tests/test_learn/test_explain_properties.py +307 -0
- tests/test_patterns_cli.py +611 -0
- tests/test_patterns_docstrings.py +473 -0
- tests/test_patterns_logger.py +465 -0
- tests/test_patterns_menu.py +440 -0
- tests/test_patterns_storage.py +447 -0
- tests/test_readme_enhancements_v0_3_1.py +2036 -0
- tests/test_readme_transformer/__init__.py +1 -0
- tests/test_readme_transformer/test_readme_infrastructure.py +1023 -0
- tests/test_readme_transformer/test_transform_readme_integration.py +431 -0
- tests/test_safe/test_files.py +726 -1
- fishertools-0.2.1.dist-info/METADATA +0 -256
- fishertools-0.2.1.dist-info/RECORD +0 -81
- {fishertools-0.2.1.dist-info → fishertools-0.4.0.dist-info}/licenses/LICENSE +0 -0
- {fishertools-0.2.1.dist-info → fishertools-0.4.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unit tests for the SessionManager class.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
import json
|
|
7
|
+
import tempfile
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from fishertools.learn.repl.session_manager import SessionManager
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TestSessionManagerBasic:
|
|
13
|
+
"""Test basic session manager functionality."""
|
|
14
|
+
|
|
15
|
+
def test_create_session_manager(self):
|
|
16
|
+
"""Test creating a session manager."""
|
|
17
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
18
|
+
manager = SessionManager(tmpdir)
|
|
19
|
+
assert manager is not None
|
|
20
|
+
assert manager.storage_path == Path(tmpdir)
|
|
21
|
+
|
|
22
|
+
def test_mark_topic_viewed(self):
|
|
23
|
+
"""Test marking a topic as viewed."""
|
|
24
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
25
|
+
manager = SessionManager(tmpdir)
|
|
26
|
+
manager.mark_topic_viewed("Lists")
|
|
27
|
+
|
|
28
|
+
viewed = manager.get_viewed_topics()
|
|
29
|
+
assert "Lists" in viewed
|
|
30
|
+
|
|
31
|
+
def test_mark_multiple_topics_viewed(self):
|
|
32
|
+
"""Test marking multiple topics as viewed."""
|
|
33
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
34
|
+
manager = SessionManager(tmpdir)
|
|
35
|
+
manager.mark_topic_viewed("Lists")
|
|
36
|
+
manager.mark_topic_viewed("Dictionaries")
|
|
37
|
+
manager.mark_topic_viewed("For Loops")
|
|
38
|
+
|
|
39
|
+
viewed = manager.get_viewed_topics()
|
|
40
|
+
assert len(viewed) == 3
|
|
41
|
+
assert "Lists" in viewed
|
|
42
|
+
assert "Dictionaries" in viewed
|
|
43
|
+
assert "For Loops" in viewed
|
|
44
|
+
|
|
45
|
+
def test_mark_example_executed(self):
|
|
46
|
+
"""Test marking an example as executed."""
|
|
47
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
48
|
+
manager = SessionManager(tmpdir)
|
|
49
|
+
manager.mark_example_executed("Lists", 1)
|
|
50
|
+
|
|
51
|
+
executed = manager.get_executed_examples()
|
|
52
|
+
assert "Lists" in executed
|
|
53
|
+
assert 1 in executed["Lists"]
|
|
54
|
+
|
|
55
|
+
def test_mark_multiple_examples_executed(self):
|
|
56
|
+
"""Test marking multiple examples as executed."""
|
|
57
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
58
|
+
manager = SessionManager(tmpdir)
|
|
59
|
+
manager.mark_example_executed("Lists", 1)
|
|
60
|
+
manager.mark_example_executed("Lists", 2)
|
|
61
|
+
manager.mark_example_executed("Dictionaries", 1)
|
|
62
|
+
|
|
63
|
+
executed = manager.get_executed_examples()
|
|
64
|
+
assert len(executed["Lists"]) == 2
|
|
65
|
+
assert len(executed["Dictionaries"]) == 1
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class TestSessionManagerProgress:
|
|
69
|
+
"""Test progress tracking functionality."""
|
|
70
|
+
|
|
71
|
+
def test_get_progress_empty(self):
|
|
72
|
+
"""Test getting progress with no activity."""
|
|
73
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
74
|
+
manager = SessionManager(tmpdir)
|
|
75
|
+
progress = manager.get_progress()
|
|
76
|
+
|
|
77
|
+
assert progress.viewed_topics == 0
|
|
78
|
+
assert progress.executed_examples == 0
|
|
79
|
+
|
|
80
|
+
def test_get_progress_with_activity(self):
|
|
81
|
+
"""Test getting progress with activity."""
|
|
82
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
83
|
+
manager = SessionManager(tmpdir)
|
|
84
|
+
manager.mark_topic_viewed("Lists")
|
|
85
|
+
manager.mark_topic_viewed("Dictionaries")
|
|
86
|
+
manager.mark_example_executed("Lists", 1)
|
|
87
|
+
manager.mark_example_executed("Lists", 2)
|
|
88
|
+
|
|
89
|
+
progress = manager.get_progress()
|
|
90
|
+
assert progress.viewed_topics == 2
|
|
91
|
+
assert progress.executed_examples == 2
|
|
92
|
+
|
|
93
|
+
def test_progress_stats_structure(self):
|
|
94
|
+
"""Test that progress stats have correct structure."""
|
|
95
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
96
|
+
manager = SessionManager(tmpdir)
|
|
97
|
+
progress = manager.get_progress()
|
|
98
|
+
|
|
99
|
+
assert hasattr(progress, 'total_topics')
|
|
100
|
+
assert hasattr(progress, 'viewed_topics')
|
|
101
|
+
assert hasattr(progress, 'total_examples')
|
|
102
|
+
assert hasattr(progress, 'executed_examples')
|
|
103
|
+
assert hasattr(progress, 'session_duration')
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class TestSessionManagerCurrentTopic:
|
|
107
|
+
"""Test current topic tracking."""
|
|
108
|
+
|
|
109
|
+
def test_set_current_topic(self):
|
|
110
|
+
"""Test setting current topic."""
|
|
111
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
112
|
+
manager = SessionManager(tmpdir)
|
|
113
|
+
manager.set_current_topic("Lists")
|
|
114
|
+
|
|
115
|
+
current = manager.get_current_topic()
|
|
116
|
+
assert current == "Lists"
|
|
117
|
+
|
|
118
|
+
def test_current_topic_none_initially(self):
|
|
119
|
+
"""Test that current topic is None initially."""
|
|
120
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
121
|
+
manager = SessionManager(tmpdir)
|
|
122
|
+
current = manager.get_current_topic()
|
|
123
|
+
assert current is None
|
|
124
|
+
|
|
125
|
+
def test_change_current_topic(self):
|
|
126
|
+
"""Test changing current topic."""
|
|
127
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
128
|
+
manager = SessionManager(tmpdir)
|
|
129
|
+
manager.set_current_topic("Lists")
|
|
130
|
+
manager.set_current_topic("Dictionaries")
|
|
131
|
+
|
|
132
|
+
current = manager.get_current_topic()
|
|
133
|
+
assert current == "Dictionaries"
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class TestSessionManagerHistory:
|
|
137
|
+
"""Test session history tracking."""
|
|
138
|
+
|
|
139
|
+
def test_session_history_empty_initially(self):
|
|
140
|
+
"""Test that session history is empty initially."""
|
|
141
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
142
|
+
manager = SessionManager(tmpdir)
|
|
143
|
+
history = manager.get_session_history()
|
|
144
|
+
assert len(history) == 0
|
|
145
|
+
|
|
146
|
+
def test_session_history_tracks_topics(self):
|
|
147
|
+
"""Test that session history tracks viewed topics."""
|
|
148
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
149
|
+
manager = SessionManager(tmpdir)
|
|
150
|
+
manager.mark_topic_viewed("Lists")
|
|
151
|
+
manager.mark_topic_viewed("Dictionaries")
|
|
152
|
+
manager.mark_topic_viewed("For Loops")
|
|
153
|
+
|
|
154
|
+
history = manager.get_session_history()
|
|
155
|
+
assert len(history) == 3
|
|
156
|
+
assert history[0] == "Lists"
|
|
157
|
+
assert history[1] == "Dictionaries"
|
|
158
|
+
assert history[2] == "For Loops"
|
|
159
|
+
|
|
160
|
+
def test_session_history_no_duplicates(self):
|
|
161
|
+
"""Test that session history doesn't add duplicate consecutive topics."""
|
|
162
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
163
|
+
manager = SessionManager(tmpdir)
|
|
164
|
+
manager.mark_topic_viewed("Lists")
|
|
165
|
+
manager.mark_topic_viewed("Lists")
|
|
166
|
+
manager.mark_topic_viewed("Dictionaries")
|
|
167
|
+
|
|
168
|
+
history = manager.get_session_history()
|
|
169
|
+
# Should have 2 entries (Lists, Dictionaries)
|
|
170
|
+
assert len(history) == 2
|
|
171
|
+
|
|
172
|
+
def test_clear_session_history(self):
|
|
173
|
+
"""Test clearing session history."""
|
|
174
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
175
|
+
manager = SessionManager(tmpdir)
|
|
176
|
+
manager.mark_topic_viewed("Lists")
|
|
177
|
+
manager.mark_topic_viewed("Dictionaries")
|
|
178
|
+
|
|
179
|
+
manager.clear_session_history()
|
|
180
|
+
history = manager.get_session_history()
|
|
181
|
+
assert len(history) == 0
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
class TestSessionManagerPersistence:
|
|
185
|
+
"""Test session persistence to disk."""
|
|
186
|
+
|
|
187
|
+
def test_save_session(self):
|
|
188
|
+
"""Test saving session to disk."""
|
|
189
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
190
|
+
manager = SessionManager(tmpdir)
|
|
191
|
+
manager.mark_topic_viewed("Lists")
|
|
192
|
+
manager.mark_example_executed("Lists", 1)
|
|
193
|
+
|
|
194
|
+
success = manager.save_session()
|
|
195
|
+
assert success is True
|
|
196
|
+
assert manager.session_file.exists()
|
|
197
|
+
|
|
198
|
+
def test_load_session(self):
|
|
199
|
+
"""Test loading session from disk."""
|
|
200
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
201
|
+
# Create and save a session
|
|
202
|
+
manager1 = SessionManager(tmpdir)
|
|
203
|
+
manager1.mark_topic_viewed("Lists")
|
|
204
|
+
manager1.mark_example_executed("Lists", 1)
|
|
205
|
+
manager1.set_current_topic("Lists")
|
|
206
|
+
manager1.save_session()
|
|
207
|
+
|
|
208
|
+
# Load the session in a new manager
|
|
209
|
+
manager2 = SessionManager(tmpdir)
|
|
210
|
+
|
|
211
|
+
viewed = manager2.get_viewed_topics()
|
|
212
|
+
executed = manager2.get_executed_examples()
|
|
213
|
+
current = manager2.get_current_topic()
|
|
214
|
+
|
|
215
|
+
assert "Lists" in viewed
|
|
216
|
+
assert 1 in executed["Lists"]
|
|
217
|
+
assert current == "Lists"
|
|
218
|
+
|
|
219
|
+
def test_session_persistence_round_trip(self):
|
|
220
|
+
"""Test that session state survives save/load cycle."""
|
|
221
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
222
|
+
# Create initial session
|
|
223
|
+
manager1 = SessionManager(tmpdir)
|
|
224
|
+
manager1.mark_topic_viewed("Lists")
|
|
225
|
+
manager1.mark_topic_viewed("Dictionaries")
|
|
226
|
+
manager1.mark_example_executed("Lists", 1)
|
|
227
|
+
manager1.mark_example_executed("Lists", 2)
|
|
228
|
+
manager1.mark_example_executed("Dictionaries", 1)
|
|
229
|
+
manager1.set_current_topic("Dictionaries")
|
|
230
|
+
manager1.save_session()
|
|
231
|
+
|
|
232
|
+
# Load and verify
|
|
233
|
+
manager2 = SessionManager(tmpdir)
|
|
234
|
+
|
|
235
|
+
assert manager2.get_viewed_topics() == ["Lists", "Dictionaries"]
|
|
236
|
+
assert manager2.get_executed_examples() == {
|
|
237
|
+
"Lists": [1, 2],
|
|
238
|
+
"Dictionaries": [1]
|
|
239
|
+
}
|
|
240
|
+
assert manager2.get_current_topic() == "Dictionaries"
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
class TestSessionManagerReset:
|
|
244
|
+
"""Test progress reset functionality."""
|
|
245
|
+
|
|
246
|
+
def test_reset_progress(self):
|
|
247
|
+
"""Test resetting all progress."""
|
|
248
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
249
|
+
manager = SessionManager(tmpdir)
|
|
250
|
+
manager.mark_topic_viewed("Lists")
|
|
251
|
+
manager.mark_example_executed("Lists", 1)
|
|
252
|
+
manager.set_current_topic("Lists")
|
|
253
|
+
|
|
254
|
+
manager.reset_progress()
|
|
255
|
+
|
|
256
|
+
assert len(manager.get_viewed_topics()) == 0
|
|
257
|
+
assert len(manager.get_executed_examples()) == 0
|
|
258
|
+
assert manager.get_current_topic() is None
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
class TestSessionManagerUtilityMethods:
|
|
262
|
+
"""Test utility methods."""
|
|
263
|
+
|
|
264
|
+
def test_is_topic_viewed(self):
|
|
265
|
+
"""Test checking if topic is viewed."""
|
|
266
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
267
|
+
manager = SessionManager(tmpdir)
|
|
268
|
+
manager.mark_topic_viewed("Lists")
|
|
269
|
+
|
|
270
|
+
assert manager.is_topic_viewed("Lists") is True
|
|
271
|
+
assert manager.is_topic_viewed("Dictionaries") is False
|
|
272
|
+
|
|
273
|
+
def test_is_example_executed(self):
|
|
274
|
+
"""Test checking if example is executed."""
|
|
275
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
276
|
+
manager = SessionManager(tmpdir)
|
|
277
|
+
manager.mark_example_executed("Lists", 1)
|
|
278
|
+
|
|
279
|
+
assert manager.is_example_executed("Lists", 1) is True
|
|
280
|
+
assert manager.is_example_executed("Lists", 2) is False
|
|
281
|
+
assert manager.is_example_executed("Dictionaries", 1) is False
|
|
282
|
+
|
|
283
|
+
def test_get_examples_executed_for_topic(self):
|
|
284
|
+
"""Test getting executed examples for a topic."""
|
|
285
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
286
|
+
manager = SessionManager(tmpdir)
|
|
287
|
+
manager.mark_example_executed("Lists", 1)
|
|
288
|
+
manager.mark_example_executed("Lists", 3)
|
|
289
|
+
|
|
290
|
+
examples = manager.get_examples_executed_for_topic("Lists")
|
|
291
|
+
assert 1 in examples
|
|
292
|
+
assert 3 in examples
|
|
293
|
+
assert 2 not in examples
|
|
294
|
+
|
|
295
|
+
def test_get_session_info(self):
|
|
296
|
+
"""Test getting session information."""
|
|
297
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
298
|
+
manager = SessionManager(tmpdir)
|
|
299
|
+
manager.mark_topic_viewed("Lists")
|
|
300
|
+
manager.mark_example_executed("Lists", 1)
|
|
301
|
+
manager.set_current_topic("Lists")
|
|
302
|
+
|
|
303
|
+
info = manager.get_session_info()
|
|
304
|
+
|
|
305
|
+
assert info["current_topic"] == "Lists"
|
|
306
|
+
assert info["topics_viewed"] == 1
|
|
307
|
+
assert info["examples_executed"] == 1
|
|
308
|
+
assert "session_duration_seconds" in info
|
|
309
|
+
assert "created_at" in info
|
|
310
|
+
assert "last_updated" in info
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Property-based tests for SessionManager using Hypothesis.
|
|
3
|
+
|
|
4
|
+
**Validates: Requirements 6.5, 6.6, 9.4, 9.5**
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
import tempfile
|
|
9
|
+
from hypothesis import given, strategies as st, assume
|
|
10
|
+
from fishertools.learn.repl.session_manager import SessionManager
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TestSessionManagerProperties:
|
|
14
|
+
"""Property-based tests for session management."""
|
|
15
|
+
|
|
16
|
+
@given(st.text(min_size=1, max_size=100))
|
|
17
|
+
def test_mark_topic_viewed_consistency(self, topic_name):
|
|
18
|
+
"""
|
|
19
|
+
For any topic name, marking it as viewed should make it appear in viewed topics.
|
|
20
|
+
|
|
21
|
+
**Validates: Requirements 6.5, 6.6, 9.4, 9.5**
|
|
22
|
+
"""
|
|
23
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
24
|
+
manager = SessionManager(tmpdir)
|
|
25
|
+
manager.mark_topic_viewed(topic_name)
|
|
26
|
+
|
|
27
|
+
viewed = manager.get_viewed_topics()
|
|
28
|
+
assert topic_name in viewed
|
|
29
|
+
|
|
30
|
+
@given(st.text(min_size=1, max_size=100), st.integers(min_value=1, max_value=100))
|
|
31
|
+
def test_mark_example_executed_consistency(self, topic_name, example_num):
|
|
32
|
+
"""
|
|
33
|
+
For any topic and example number, marking it as executed should make it appear in executed examples.
|
|
34
|
+
|
|
35
|
+
**Validates: Requirements 6.5, 6.6, 9.4, 9.5**
|
|
36
|
+
"""
|
|
37
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
38
|
+
manager = SessionManager(tmpdir)
|
|
39
|
+
manager.mark_example_executed(topic_name, example_num)
|
|
40
|
+
|
|
41
|
+
executed = manager.get_executed_examples()
|
|
42
|
+
assert topic_name in executed
|
|
43
|
+
assert example_num in executed[topic_name]
|
|
44
|
+
|
|
45
|
+
@given(st.text(min_size=1, max_size=100))
|
|
46
|
+
def test_session_persistence_round_trip(self, topic_name):
|
|
47
|
+
"""
|
|
48
|
+
Property 7: Session State Persistence Round-Trip
|
|
49
|
+
|
|
50
|
+
For any session state saved to disk, loading it should restore the exact same state.
|
|
51
|
+
|
|
52
|
+
**Validates: Requirements 6.5, 6.6, 9.4, 9.5**
|
|
53
|
+
"""
|
|
54
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
55
|
+
# Create and save session
|
|
56
|
+
manager1 = SessionManager(tmpdir)
|
|
57
|
+
manager1.mark_topic_viewed(topic_name)
|
|
58
|
+
manager1.set_current_topic(topic_name)
|
|
59
|
+
manager1.save_session()
|
|
60
|
+
|
|
61
|
+
# Load session
|
|
62
|
+
manager2 = SessionManager(tmpdir)
|
|
63
|
+
|
|
64
|
+
# Verify state is identical
|
|
65
|
+
assert manager2.get_current_topic() == topic_name
|
|
66
|
+
assert topic_name in manager2.get_viewed_topics()
|
|
67
|
+
|
|
68
|
+
@given(st.lists(st.text(min_size=1, max_size=50), min_size=1, max_size=10, unique=True))
|
|
69
|
+
def test_multiple_topics_persistence(self, topic_names):
|
|
70
|
+
"""
|
|
71
|
+
For any list of topics, saving and loading should preserve all topics.
|
|
72
|
+
|
|
73
|
+
**Validates: Requirements 6.5, 6.6, 9.4, 9.5**
|
|
74
|
+
"""
|
|
75
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
76
|
+
# Create and save session with multiple topics
|
|
77
|
+
manager1 = SessionManager(tmpdir)
|
|
78
|
+
for topic in topic_names:
|
|
79
|
+
manager1.mark_topic_viewed(topic)
|
|
80
|
+
manager1.save_session()
|
|
81
|
+
|
|
82
|
+
# Load and verify
|
|
83
|
+
manager2 = SessionManager(tmpdir)
|
|
84
|
+
viewed = manager2.get_viewed_topics()
|
|
85
|
+
|
|
86
|
+
for topic in topic_names:
|
|
87
|
+
assert topic in viewed
|
|
88
|
+
|
|
89
|
+
@given(st.text(min_size=1, max_size=100), st.lists(st.integers(min_value=1, max_value=50), min_size=1, max_size=10, unique=True))
|
|
90
|
+
def test_executed_examples_persistence(self, topic_name, example_nums):
|
|
91
|
+
"""
|
|
92
|
+
For any topic and list of example numbers, saving and loading should preserve all executed examples.
|
|
93
|
+
|
|
94
|
+
**Validates: Requirements 6.5, 6.6, 9.4, 9.5**
|
|
95
|
+
"""
|
|
96
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
97
|
+
# Create and save session with executed examples
|
|
98
|
+
manager1 = SessionManager(tmpdir)
|
|
99
|
+
for example_num in example_nums:
|
|
100
|
+
manager1.mark_example_executed(topic_name, example_num)
|
|
101
|
+
manager1.save_session()
|
|
102
|
+
|
|
103
|
+
# Load and verify
|
|
104
|
+
manager2 = SessionManager(tmpdir)
|
|
105
|
+
executed = manager2.get_executed_examples()
|
|
106
|
+
|
|
107
|
+
assert topic_name in executed
|
|
108
|
+
for example_num in example_nums:
|
|
109
|
+
assert example_num in executed[topic_name]
|
|
110
|
+
|
|
111
|
+
@given(st.text(min_size=1, max_size=100))
|
|
112
|
+
def test_current_topic_persistence(self, topic_name):
|
|
113
|
+
"""
|
|
114
|
+
For any current topic, saving and loading should preserve it.
|
|
115
|
+
|
|
116
|
+
**Validates: Requirements 6.5, 6.6, 9.4, 9.5**
|
|
117
|
+
"""
|
|
118
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
119
|
+
# Create and save session
|
|
120
|
+
manager1 = SessionManager(tmpdir)
|
|
121
|
+
manager1.set_current_topic(topic_name)
|
|
122
|
+
manager1.save_session()
|
|
123
|
+
|
|
124
|
+
# Load and verify
|
|
125
|
+
manager2 = SessionManager(tmpdir)
|
|
126
|
+
assert manager2.get_current_topic() == topic_name
|
|
127
|
+
|
|
128
|
+
@given(st.lists(st.text(min_size=1, max_size=50), min_size=1, max_size=10, unique=True))
|
|
129
|
+
def test_session_history_persistence(self, topic_names):
|
|
130
|
+
"""
|
|
131
|
+
For any sequence of topics, saving and loading should preserve the session history.
|
|
132
|
+
|
|
133
|
+
**Validates: Requirements 6.5, 6.6, 9.4, 9.5**
|
|
134
|
+
"""
|
|
135
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
136
|
+
# Create and save session with history
|
|
137
|
+
manager1 = SessionManager(tmpdir)
|
|
138
|
+
for topic in topic_names:
|
|
139
|
+
manager1.mark_topic_viewed(topic)
|
|
140
|
+
manager1.save_session()
|
|
141
|
+
|
|
142
|
+
# Load and verify
|
|
143
|
+
manager2 = SessionManager(tmpdir)
|
|
144
|
+
history = manager2.get_session_history()
|
|
145
|
+
|
|
146
|
+
assert len(history) == len(topic_names)
|
|
147
|
+
for i, topic in enumerate(topic_names):
|
|
148
|
+
assert history[i] == topic
|
|
149
|
+
|
|
150
|
+
@given(st.text(min_size=1, max_size=100))
|
|
151
|
+
def test_is_topic_viewed_after_persistence(self, topic_name):
|
|
152
|
+
"""
|
|
153
|
+
For any topic marked as viewed, after persistence it should still be marked as viewed.
|
|
154
|
+
|
|
155
|
+
**Validates: Requirements 6.5, 6.6, 9.4, 9.5**
|
|
156
|
+
"""
|
|
157
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
158
|
+
# Create and save session
|
|
159
|
+
manager1 = SessionManager(tmpdir)
|
|
160
|
+
manager1.mark_topic_viewed(topic_name)
|
|
161
|
+
manager1.save_session()
|
|
162
|
+
|
|
163
|
+
# Load and verify
|
|
164
|
+
manager2 = SessionManager(tmpdir)
|
|
165
|
+
assert manager2.is_topic_viewed(topic_name) is True
|
|
166
|
+
|
|
167
|
+
@given(st.text(min_size=1, max_size=100), st.integers(min_value=1, max_value=50))
|
|
168
|
+
def test_is_example_executed_after_persistence(self, topic_name, example_num):
|
|
169
|
+
"""
|
|
170
|
+
For any example marked as executed, after persistence it should still be marked as executed.
|
|
171
|
+
|
|
172
|
+
**Validates: Requirements 6.5, 6.6, 9.4, 9.5**
|
|
173
|
+
"""
|
|
174
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
175
|
+
# Create and save session
|
|
176
|
+
manager1 = SessionManager(tmpdir)
|
|
177
|
+
manager1.mark_example_executed(topic_name, example_num)
|
|
178
|
+
manager1.save_session()
|
|
179
|
+
|
|
180
|
+
# Load and verify
|
|
181
|
+
manager2 = SessionManager(tmpdir)
|
|
182
|
+
assert manager2.is_example_executed(topic_name, example_num) is True
|