Skip to content

Commit 6754942

Browse files
committed
Merge branch 'include-stderr'
2 parents 0852ce1 + c4806e3 commit 6754942

File tree

4 files changed

+93
-37
lines changed

4 files changed

+93
-37
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2020

2121
### Fixed
2222

23+
## [v0.1.10] - 2025-02-26
24+
25+
### Changed
26+
* Will include available `stderr` values when generating comments. Expected to be helpful sometimes.
27+
2328
## [v0.1.9] - 2025-02-22
2429

2530
### Changed

ai_tutor.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@ def collect_longrepr(data:Dict[str, str]) -> List[str]:
196196
if r['outcome'] != 'passed':
197197
for k in r:
198198
if isinstance(r[k], dict) and 'longrepr' in r[k]:
199-
longrepr_list.append(r['outcome'] + ':' + k + ':' + r[k]['longrepr'])
199+
longrepr_list.append(r['outcome'] + ':' + k + ': longrepr begin :' + r[k]['longrepr'] + ': longrepr end \n')
200+
if isinstance(r[k], dict) and 'stderr' in r[k]:
201+
longrepr_list.append(r['outcome'] + ':' + k + ': stderr begin' + r[k]['stderr'] + ': stderr end \n')
200202
return longrepr_list
201203

202204

tests/sample_report.json

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@
3737
"message": ";) 8) ;D :) ;P"
3838
}
3939
],
40-
"longrepr": ";P ;D ;) 8) :)"
40+
"longrepr": "longrepr100 ;P ;D ;) 8) :)"
4141
},
4242
"teardown": {
4343
"duration": "8) :) ;P ;) ;D",
4444
"outcome": "8) :) ;D ;) ;P",
45-
"longrepr": ":) ;D 8) ;) ;P"
45+
"longrepr": "longrepr110 :) ;D 8) ;) ;P"
4646
}
4747
},
4848
{
@@ -71,12 +71,14 @@
7171
"message": ";D ;P ;) :) 8)"
7272
}
7373
],
74-
"longrepr": ";D ;P :) 8) ;)"
74+
"longrepr": "longrepr200 ;D ;P :) 8) ;)",
75+
"stderr": "stderr200 ? ?? ???"
7576
},
7677
"teardown": {
7778
"duration": "8) ;P :) ;D ;)",
7879
"outcome": ";P ;D 8) :) ;)",
79-
"longrepr": ";) :) ;D ;P 8)"
80+
"longrepr": "longrepr210 ;) :) ;D ;P 8)",
81+
"stderr": "stderr210 ? ?? ???"
8082
}
8183
},
8284
{
@@ -105,12 +107,12 @@
105107
"message": "8) :) ;) ;D ;P"
106108
}
107109
],
108-
"longrepr": ";D 8) ;P :) ;)"
110+
"longrepr": "longrepr300 ;D 8) ;P :) ;)"
109111
},
110112
"teardown": {
111113
"duration": "8) ;) ;P ;D :)",
112114
"outcome": "8) ;D :) ;P ;)",
113-
"longrepr": ";P :) ;) ;D 8)"
115+
"longrepr": "longrepr310 ;P :) ;) ;D 8)"
114116
}
115117
},
116118
{
@@ -139,12 +141,12 @@
139141
"message": ":) ;) ;D ;P 8)"
140142
}
141143
],
142-
"longrepr": ";) 8) :) ;D ;P"
144+
"longrepr": "longrepr400 ;) 8) :) ;D ;P"
143145
},
144146
"teardown": {
145147
"duration": ";D 8) ;P ;) :)",
146148
"outcome": ";D 8) :) ;P ;)",
147-
"longrepr": ";) ;P :) 8) ;D"
149+
"longrepr": "longrepr410;) ;P :) 8) ;D"
148150
}
149151
},
150152
{
@@ -162,17 +164,17 @@
162164
"setup": {
163165
"duration": "8) :) ;D ;) ;P",
164166
"outcome": "8) ;P ;) ;D :)",
165-
"longrepr": "8) ;D :) ;) ;P"
167+
"longrepr": "longrepr500 8) ;D :) ;) ;P"
166168
},
167169
"call": {
168170
"duration": ";) :) ;P 8) ;D",
169171
"outcome": ";) ;P 8) :) ;D",
170-
"longrepr": ";) 8) :) ;D ;P"
172+
"longrepr": "longrepr510;) 8) :) ;D ;P"
171173
},
172174
"teardown": {
173175
"duration": ";) 8) ;P :) ;D",
174176
"outcome": "8) :) ;) ;D ;P",
175-
"longrepr": ";D 8) :) ;) ;P"
177+
"longrepr": "longrepr520 ;D 8) :) ;) ;P"
176178
}
177179
},
178180
{
@@ -190,17 +192,17 @@
190192
"setup": {
191193
"duration": ":) ;) ;D 8) ;P",
192194
"outcome": ";P 8) ;D :) ;)",
193-
"longrepr": "8) :) ;D ;) ;P"
195+
"longrepr": "longrepr600 8) :) ;D ;) ;P"
194196
},
195197
"call": {
196198
"duration": "8) ;D ;) ;P :)",
197199
"outcome": ";) ;D :) ;P 8)",
198-
"longrepr": ";P :) 8) ;D ;)"
200+
"longrepr": "longrepr610 ;P :) 8) ;D ;)"
199201
},
200202
"teardown": {
201203
"duration": "8) :) ;P ;) ;D",
202204
"outcome": "8) ;D ;) :) ;P",
203-
"longrepr": "8) ;P :) ;) ;D"
205+
"longrepr": "longrepr620 8) ;P :) ;) ;D"
204206
}
205207
},
206208
{
@@ -218,17 +220,17 @@
218220
"setup": {
219221
"duration": ";P ;) :) 8) ;D",
220222
"outcome": ":) ;D 8) ;P ;)",
221-
"longrepr": ";) ;P :) 8) ;D"
223+
"longrepr": "longrepr700 ;) ;P :) 8) ;D"
222224
},
223225
"call": {
224226
"duration": "8) ;D ;) :) ;P",
225227
"outcome": ";) :) ;P ;D 8)",
226-
"longrepr": ";P ;D :) ;) 8)"
228+
"longrepr": "longrepr710 ;P ;D :) ;) 8)"
227229
},
228230
"teardown": {
229231
"duration": ";P :) ;) ;D 8)",
230232
"outcome": ";P ;D ;) 8) :)",
231-
"longrepr": ";D :) ;P 8) ;)"
233+
"longrepr": "longrepr720 ;D :) ;P 8) ;)"
232234
}
233235
},
234236
{
@@ -246,17 +248,17 @@
246248
"setup": {
247249
"duration": ";D ;P :) ;) 8)",
248250
"outcome": ";D ;P :) ;) 8)",
249-
"longrepr": ";) 8) ;D ;P :)"
251+
"longrepr": "longrepr800 ;) 8) ;D ;P :)"
250252
},
251253
"call": {
252254
"duration": ";) ;D 8) ;P :)",
253255
"outcome": "8) ;) ;D ;P :)",
254-
"longrepr": ";) ;P 8) ;D :)"
256+
"longrepr": "longrepr810;) ;P 8) ;D :)"
255257
},
256258
"teardown": {
257259
"duration": "8) ;D :) ;P ;)",
258260
"outcome": ";P 8) ;) ;D :)",
259-
"longrepr": "8) ;P ;D :) ;)"
261+
"longrepr": "longrepr820 8) ;P ;D :) ;)"
260262
}
261263
},
262264
{
@@ -274,17 +276,17 @@
274276
"setup": {
275277
"duration": "8) ;D ;) :) ;P",
276278
"outcome": ";D ;) 8) :) ;P",
277-
"longrepr": ":) ;) ;P 8) ;D"
279+
"longrepr": "longrepr900 :) ;) ;P 8) ;D"
278280
},
279281
"call": {
280282
"duration": ";) ;D ;P 8) :)",
281283
"outcome": "8) ;) :) ;D ;P",
282-
"longrepr": ";P ;D 8) ;) :)"
284+
"longrepr": "longrepr910 ;P ;D 8) ;) :)"
283285
},
284286
"teardown": {
285287
"duration": ":) 8) ;P ;) ;D",
286288
"outcome": "8) ;D :) ;P ;)",
287-
"longrepr": ";) ;P ;D :) 8)"
289+
"longrepr": "longrepr920 ;) ;P ;D :) 8)"
288290
}
289291
},
290292
{
@@ -302,17 +304,17 @@
302304
"setup": {
303305
"duration": ";D 8) :) ;) ;P",
304306
"outcome": ";P ;D 8) ;) :)",
305-
"longrepr": ";D ;P 8) ;) :)"
307+
"longrepr": "longrepr1000 ;D ;P 8) ;) :)"
306308
},
307309
"call": {
308310
"duration": ";) ;P 8) ;D :)",
309311
"outcome": ";) ;P ;D 8) :)",
310-
"longrepr": "8) ;D ;P ;) :)"
312+
"longrepr": "longrepr1010 8) ;D ;P ;) :)"
311313
},
312314
"teardown": {
313315
"duration": ";P :) 8) ;D ;)",
314316
"outcome": ";P 8) :) ;) ;D",
315-
"longrepr": ";) ;D 8) ;P :)"
317+
"longrepr": "longrepr1020 ;) ;D 8) ;P :)"
316318
}
317319
},
318320
{
@@ -330,17 +332,17 @@
330332
"setup": {
331333
"duration": ";D ;P :) ;) 8)",
332334
"outcome": "8) :) ;D ;) ;P",
333-
"longrepr": ";D 8) ;) ;P :)"
335+
"longrepr": "longrepr1100 ;D 8) ;) ;P :)"
334336
},
335337
"call": {
336338
"duration": ":) ;D ;) 8) ;P",
337339
"outcome": ":) ;P ;) ;D 8)",
338-
"longrepr": ":) ;) ;D 8) ;P"
340+
"longrepr": "longrepr1110 :) ;) ;D 8) ;P"
339341
},
340342
"teardown": {
341343
"duration": ";D ;) ;P :) 8)",
342344
"outcome": "8) ;D ;P ;) :)",
343-
"longrepr": ";) ;D 8) :) ;P"
345+
"longrepr": "longrepr1120;) ;D 8) :) ;P"
344346
}
345347
},
346348
{
@@ -358,17 +360,17 @@
358360
"setup": {
359361
"duration": ";D :) ;) 8) ;P",
360362
"outcome": ";) ;D 8) :) ;P",
361-
"longrepr": "8) ;P ;) :) ;D"
363+
"longrepr": "longrepr1200 8) ;P ;) :) ;D"
362364
},
363365
"call": {
364366
"duration": "8) ;) ;P ;D :)",
365367
"outcome": ":) ;) 8) ;P ;D",
366-
"longrepr": "8) ;) ;D :) ;P"
368+
"longrepr": "longrepr1210 8) ;) ;D :) ;P"
367369
},
368370
"teardown": {
369371
"duration": ";P 8) ;) ;D :)",
370372
"outcome": ":) ;) ;D 8) ;P",
371-
"longrepr": ";D 8) ;) ;P :)"
373+
"longrepr": "longrepr1220 ;D 8) ;) ;P :)"
372374
}
373375
}
374376
]

tests/test_ai_tutor.py

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
from typing import Callable, Dict, List, Tuple, Union
77

88

9+
PYTEST_JSON_REPORT = Dict[str, Union[str, List]]
10+
11+
912
import pytest
1013

1114

@@ -22,19 +25,20 @@
2225
import ai_tutor
2326

2427

28+
2529
@pytest.fixture
2630
def sample_report_path() -> pathlib.Path:
2731
return test_folder / 'sample_report.json'
2832

2933

3034
@pytest.fixture
31-
def json_dict(sample_report_path) -> Dict[str, Union[str, List]]:
35+
def json_dict(sample_report_path) -> PYTEST_JSON_REPORT:
3236
with sample_report_path.open('rt') as f:
3337
result = json.load(f)
3438
return result
3539

3640

37-
def test_collect_longrepr__returns_non_empty(json_dict):
41+
def test_collect_longrepr__returns_non_empty(json_dict:PYTEST_JSON_REPORT):
3842
result = ai_tutor.collect_longrepr(json_dict)
3943

4044
assert result
@@ -46,13 +50,13 @@ def div_zero_report_path() -> pathlib.Path:
4650

4751

4852
@pytest.fixture
49-
def json_dict_div_zero_try_except(div_zero_report_path:pathlib.Path) -> Dict[str, Union[str, List]]:
53+
def json_dict_div_zero_try_except(div_zero_report_path:pathlib.Path) -> PYTEST_JSON_REPORT:
5054
with div_zero_report_path.open('rt') as f:
5155
result = json.load(f)
5256
return result
5357

5458

55-
def test_collect_longrepr_div_zero_dict__returns_non_empty(json_dict_div_zero_try_except:Dict):
59+
def test_collect_longrepr_div_zero_dict__returns_non_empty(json_dict_div_zero_try_except:PYTEST_JSON_REPORT):
5660
result = ai_tutor.collect_longrepr(json_dict_div_zero_try_except)
5761

5862
assert result
@@ -603,5 +607,48 @@ def test_url__specific_model(
603607
assert b_found, f"Could not find {expected_default_gemini_model} in {path_parts}."
604608

605609

610+
@pytest.fixture
611+
def collect_longrepr_result(json_dict:PYTEST_JSON_REPORT) -> List[str]:
612+
return ai_tutor.collect_longrepr(json_dict)
613+
614+
615+
def test__collect_longrepr__is_list(collect_longrepr_result:List[str]):
616+
assert isinstance(collect_longrepr_result, list), f"Expected list, got {type(collect_longrepr_result)}."
617+
618+
619+
def test__collect_longrepr__has_list_items(collect_longrepr_result:List[str]):
620+
assert collect_longrepr_result, "Expected non-empty list, got empty list."
621+
622+
623+
def test__collect_longrepr__has_list_items_len(collect_longrepr_result:List[str]):
624+
for s in collect_longrepr_result:
625+
assert isinstance(s, str), f"Expected string, has {s} which is {type(s)}."
626+
assert s, "Expected non-empty string, got empty string."
627+
628+
629+
def test__collect_longrepr__compare_contents(collect_longrepr_result:List[str]):
630+
markers = 'longrepr100 longrepr110'.split()
631+
markers += 'longrepr200 longrepr210'.split()
632+
markers += 'longrepr300 longrepr310'.split()
633+
markers += 'longrepr400 longrepr410'.split()
634+
markers += 'longrepr500 longrepr510 longrepr520'.split()
635+
markers += 'longrepr600 longrepr610 longrepr620'.split()
636+
markers += 'longrepr700 longrepr710 longrepr720'.split()
637+
markers += 'longrepr800 longrepr810 longrepr820'.split()
638+
markers += 'longrepr900 longrepr910 longrepr920'.split()
639+
markers += 'longrepr1000 longrepr1010 longrepr1020'.split()
640+
markers += 'longrepr1100 longrepr1110 longrepr1120'.split()
641+
markers += 'longrepr1200 longrepr1210 longrepr1220'.split()
642+
643+
markers += 'stderr200 stderr210'.split()
644+
645+
for s in collect_longrepr_result:
646+
for marker in markers:
647+
if marker in s:
648+
markers.remove(marker)
649+
650+
assert not markers, f"Expected all markers to be found, but missing: {markers}."
651+
652+
606653
if '__main__' == __name__:
607654
pytest.main([__file__])

0 commit comments

Comments
 (0)