@@ -18,14 +18,55 @@ def test_result_ok_initialization():
1818def test_result_err_initialization ():
1919 error_message = "An error occurred"
2020 result = Result .as_Err (error_message )
21+ assert result .unwrap () == Err (error_message )
2122 assert result .is_Ok is False
2223 assert result .is_Err is True
2324
2425 with pytest .raises (ResultErr ):
25- result .expect ()
26+ _ = result .Ok
2627
2728 with pytest .raises (ResultErr ):
28- result .raises ()
29+ _ = result .expect ()
30+
31+ with pytest .raises (ResultErr ):
32+ _ = result .raises ()
33+
34+
35+ def test_result_ok_operation ():
36+ result = Ok (10 )
37+
38+ # Arithmetic operations
39+ result2 = Ok (20 )
40+ result_sum = result + result2
41+ assert result_sum .is_Ok
42+ assert result_sum .unwrap () == 30
43+
44+ # Chaining operations
45+ mapped_result = result .map (lambda x : x * 2 )
46+ assert mapped_result .unwrap () == 20
47+
48+ applied_result = result .apply (lambda x : x + 5 )
49+ assert applied_result .unwrap () == 15
50+
51+
52+ def test_result_err_operation ():
53+ error = Err ("Initial error" )
54+
55+ # Adding messages
56+ error .add_Err_msg ("Additional context" )
57+ assert "Additional context" in error .Err_msg
58+
59+ # Checking tracebacks
60+ assert error .Err_traceback is not None
61+
62+ # apply_Err method
63+ result = error .apply_Err (lambda e : e .append ("Another error msg" , False ))
64+
65+ assert result .Err_msg_contains ("Initial error" )
66+ assert result .Err_msg_contains ("Additional context" )
67+ assert result .Err_msg_contains ("Another error msg" )
68+
69+ assert result .unwrap ().msg == ["Initial error" , "Additional context" , "Another error msg" ]
2970
3071
3172# Basic Initialization Tests
@@ -39,23 +80,6 @@ def test_result_ok_attribute():
3980 _ = result .Err
4081
4182
42- def test_result_err_initialization ():
43- error_message = "An error occurred"
44- result = Result .as_Err (error_message )
45- assert result .unwrap () == Err (error_message )
46- assert result .is_Ok is False
47- assert result .is_Err is True
48-
49- with pytest .raises (ResultErr ):
50- _ = result .Ok
51-
52- with pytest .raises (ResultErr ):
53- result .expect ()
54-
55- with pytest .raises (ResultErr ):
56- result .raises ()
57-
58-
5983# Edge Case Initialization
6084def test_result_ok_with_none ():
6185 result = Result .as_Ok (None )
@@ -76,6 +100,33 @@ def test_result_err_with_empty_string():
76100 result .raises ()
77101
78102
103+ # Ok_and and Ok_or
104+ def test_result_Ok_and ():
105+ ok2 = Ok (2 )
106+ ok4 = Ok (4 )
107+ er6 = Err (6 )
108+ er8 = Err (8 )
109+
110+ assert ok2 .Ok_and (ok4 ) == ok4
111+ assert ok2 .Ok_and (er8 ) == er8
112+
113+ assert er6 .Ok_and (ok4 ) == er6
114+ assert er6 .Ok_and (er8 ) == er6
115+
116+
117+ def test_result_Ok_or ():
118+ ok2 = Ok (2 )
119+ ok4 = Ok (4 )
120+ er6 = Err (6 )
121+ er8 = Err (8 )
122+
123+ assert ok2 .Ok_or (ok4 ) == ok2
124+ assert ok2 .Ok_or (er8 ) == ok2
125+
126+ assert er6 .Ok_or (ok4 ) == ok4
127+ assert er6 .Ok_or (er8 ) == er8
128+
129+
79130# Iter Tests
80131def test_iter_err ():
81132 result = Err (10 )
@@ -94,6 +145,23 @@ def test_iter_scalar():
94145 assert enter_loop
95146
96147
148+ def test_iter_and_copy ():
149+ """Test iteration and copying functionality of Result."""
150+ result = Ok ([1 , 2 , 3 ])
151+
152+ # Iteration
153+ iterated = [x for x in result .iter_wrap ()]
154+ assert iterated == [1 , 2 , 3 ]
155+
156+ # Copy
157+ copied_result = result .copy ()
158+ assert copied_result == result
159+
160+ # Clear
161+ result .unwrap ().clear ()
162+ assert len (result .unwrap ()) == 0
163+
164+
97165def test_iter_list ():
98166 lst = [0 , 1 , 2 , 3 ]
99167 result = Result .as_Ok (lst )
@@ -202,6 +270,20 @@ def test_result_apply():
202270 mapped_result .raises ()
203271
204272
273+ def test_result_map_simple ():
274+ """Test mapping functions on Result."""
275+ result = Ok (5 )
276+
277+ # Map
278+ mapped_result = result .map (lambda x : x * 2 )
279+ assert mapped_result .unwrap () == 10
280+
281+ # Map with fallback
282+ result = Result .as_Err ("Error" )
283+ mapped_fallback = result .map_or (100 , lambda x : x * 2 )
284+ assert mapped_fallback == 100
285+
286+
205287def test_result_map ():
206288 result = Result .as_Ok (10 )
207289 mapped_result = result .map (lambda x : x * 2 )
@@ -252,217 +334,6 @@ def test_result_map_err():
252334 assert ok_result .expect () == 10
253335
254336
255- def test_result_apply_chain ():
256- new_result = (
257- Ok (10 )
258- .apply (lambda x : Ok (x * 2 )) # Ok(20)
259- .apply (lambda x : Ok (x * 2 )) # Ok(40)
260- .apply (lambda x : Ok (x * 2 )) # Ok(80)
261- .apply (lambda x : Ok (x * 2 )) # Ok(160)
262- )
263- assert new_result .is_Ok is True
264- assert new_result .expect () == 160
265-
266- error_result = (
267- Err ("Error" )
268- .apply (lambda x : Ok (x * 2 )) # Appends to error
269- .apply (lambda x : Ok (x * 2 )) # Appends to error
270- .apply (lambda x : Ok (x * 2 )) # Appends to error
271- )
272- assert error_result .is_Err is True
273- with pytest .raises (ResultErr ):
274- error_result .expect ()
275-
276- result_error = Ok (10 )
277- # Separated
278- new_result = result_error .apply (lambda x : Result .as_Ok (x * 2 )).apply (lambda x : Result .as_Ok (x * 2 ))
279- assert new_result .is_Err is False
280- new_result = new_result .apply (lambda x : Result .as_Ok (x * 0 )).apply (lambda x : Result .as_Ok (10 / x ))
281- assert new_result .is_Err is True
282-
283- with pytest .raises (ResultErr ):
284- new_result = (
285- Ok (10 )
286- .apply (lambda x : Ok (x * 2 )) # Ok(20)
287- .apply (lambda x : Ok (x * 2 )) # Ok(40)
288- .apply (lambda x : Ok (x * 0 )) # Ok(40)
289- .apply (lambda x : Ok (10 / x )) # Raises ZeroDiv Error
290- .apply (lambda x : Ok (x + 1 )) # Appends to error message
291- .raises () # Raises Exception if in Err state
292- )
293-
294-
295- def test_result_method_chain ():
296- from math import sqrt
297-
298- def div (numerator , denominator ):
299- return numerator / denominator
300-
301- def plus11 (x , * args ):
302- # *args not used, but needed because apply_or_else(efunc, ofunc) requires
303- # both functions to have the same arg length, see `apply_or_else(plus11, div, 0)` or `.apply_or_else(plus11, div, 2)`
304- return x + 11
305-
306- def pow2 (x ):
307- return x ** 2
308-
309- def neg (x , * args ):
310- # *args not used, but needed because apply_or_else(efunc, ofunc) requires
311- # both functions to have the same arg length, see `.apply_or_else(neg, div, 0)`
312- return - x
313-
314- a = Ok (5 )
315-
316- with pytest .raises (ValueError ):
317- fail1 = a .map (pow2 ).map (plus11 ).map (sqrt ).map (neg ).map (sqrt )
318- # 5 -> 25 -> 36 -> 6 -> -6 -> raise ValueError
319-
320- with pytest .raises (ValueError ):
321- fail2 = a .map (pow2 ).map (plus11 ).map (sqrt ).map (neg ).map_or (None , sqrt )
322- # 5 -> 25 -> 36 -> 6 -> -6 -> raise ValueError
323-
324- b = (
325- a .apply (pow2 ) # Ok(5) -> Ok(25)
326- .apply (plus11 ) # -> Ok(36)
327- .apply (sqrt ) # -> Ok(6)
328- .apply (neg ) # -> Ok(-6)
329- .apply (sqrt ) # -> Err("Result.apply exception | ValueError: math domain error")
330- )
331-
332- c = (
333- a .apply (pow2 ) # Ok(5) -> Ok(25)
334- .apply (plus11 ) # -> Ok(36)
335- .apply (sqrt ) # -> Ok(6)
336- .apply (neg ) # -> Ok(-6)
337- .apply_or (None , sqrt ) # -> Ok(None)
338- )
339-
340- d = (
341- a .apply (pow2 ) # Ok(5) -> Ok(25)
342- .apply (plus11 ) # -> Ok(36)
343- .apply (sqrt ) # -> Ok(6)
344- .apply (neg ) # -> Ok(3)
345- .apply_or_else (plus11 , sqrt ) # -> Ok(5)
346- )
347-
348- e = (
349- a .apply (pow2 ) # Ok(5) -> Ok(25)
350- .apply (plus11 ) # -> Ok(36)
351- .apply (sqrt ) # -> Ok(6)
352- .apply (div , 2 ) # -> Ok(3)
353- .apply (div , 0 ) # -> Err("Result.apply exception | ZeroDivisionError: float division by zero")
354- )
355- # 5 -> 25 -> 36 -> 6 -> 3 -> Err("Result.apply exception | ZeroDivisionError: float division by zero")
356-
357- f = (
358- a .apply (pow2 ) # Ok(5) -> Ok(25)
359- .apply (plus11 ) # -> Ok(36)
360- .apply (sqrt ) # -> Ok(6)
361- .apply (div , 2 ) # -> Ok(3)
362- .apply_or_else (plus11 , div , 0 ) # -> Ok(14)
363- )
364-
365- g = (
366- a .apply (pow2 ) # Ok(5) -> Ok(25)
367- .apply (plus11 ) # -> Ok(36)
368- .apply (sqrt ) # -> Ok(6)
369- .apply_or_else (neg , div , 0 ) # -> Ok(-6)
370- .apply_or_else (plus11 , div , 2 ) # -> Ok(-3)
371- )
372-
373- assert a .is_Ok and a == Ok (5 )
374- assert b .is_Err and b .Err_msg_contains ("ValueError" )
375- assert c .is_Ok and c == Ok (None )
376- assert d .is_Ok and d == Ok (5 )
377- assert e .is_Err and e .Err_msg_contains ("ZeroDivisionError" )
378- assert f .is_Ok and f == Ok (14 )
379- assert g .is_Ok and g == Ok (- 3 )
380-
381-
382- def test_result_method_chain_lambda ():
383- from math import sqrt
384- # div = lambda x, y: x / y
385- # plus11 = lambda x: x + 11
386- # pow2 = lambda x: x**2
387- # neg = lambda x: -x
388-
389- a = Ok (5 )
390-
391- with pytest .raises (ValueError ):
392- fail1 = (
393- a .map (lambda x : x ** 2 ) # Ok(5) -> Ok(25)
394- .map (lambda x : x + 11 ) # -> Ok(36)
395- .map (sqrt ) # -> Ok(6)
396- .map (lambda x : - x ) # -> Ok(-6)
397- .map (sqrt ) # -> raise ValueError
398- )
399-
400- with pytest .raises (ValueError ):
401- fail2 = (
402- a .map (lambda x : x ** 2 ) # Ok(5) -> Ok(25)
403- .map (lambda x : x + 11 ) # -> Ok(36)
404- .map (sqrt ) # -> Ok(6)
405- .map (lambda x : - x ) # -> Ok(-6)
406- .map_or (None , sqrt ) # -> raise ValueError
407- )
408-
409- b = (
410- a .apply (lambda x : x ** 2 ) # Ok(5) -> Ok(25)
411- .apply (lambda x : x + 11 ) # -> Ok(36)
412- .apply (sqrt ) # -> Ok(6)
413- .apply (lambda x : - x ) # -> Ok(-6)
414- .apply (sqrt ) # -> Err("Result.apply exception | ValueError: math domain error")
415- )
416-
417- c = (
418- a .apply (lambda x : x ** 2 ) # Ok(5) -> Ok(25)
419- .apply (lambda x : x + 11 ) # -> Ok(36)
420- .apply (sqrt ) # -> Ok(6)
421- .apply (lambda x : - x ) # -> Ok(-6)
422- .apply_or (None , sqrt ) # -> Ok(None)
423- )
424-
425- d = (
426- a .apply (lambda x : x ** 2 ) # Ok(5) -> Ok(25)
427- .apply (lambda x : x + 11 ) # -> Ok(36)
428- .apply (sqrt ) # -> Ok(6)
429- .apply (lambda x : - x ) # -> Ok(-6)
430- .apply_or_else (lambda x : x + 11 , sqrt ) # -> Ok(5)
431- )
432-
433- e = (
434- a .apply (lambda x : x ** 2 ) # Ok(5) -> Ok(25)
435- .apply (lambda x : x + 11 ) # -> Ok(36)
436- .apply (sqrt ) # -> Ok(6)
437- .apply (lambda x , y : x / y , 2 ) # -> Ok(3)
438- .apply (lambda x , y : x / y , 0 ) # -> Err("Result.apply exception | ZeroDivisionError: float division by zero")
439- )
440-
441- f = (
442- a .apply (lambda x : x ** 2 ) # Ok(5) -> Ok(25)
443- .apply (lambda x : x + 11 ) # -> Ok(36)
444- .apply (sqrt ) # -> Ok(6)
445- .apply (lambda x , y : x / y , 2 ) # -> Ok(3)
446- .apply_or_else (lambda x , y : x + 11 , lambda x , y : x / y , 0 ) # -> Ok(14)
447- )
448-
449- g = (
450- a .apply (lambda x : x ** 2 ) # Ok(5) -> Ok(25)
451- .apply (lambda x : x + 11 ) # -> Ok(36)
452- .apply (sqrt ) # -> Ok(6)
453- .apply_or_else (lambda x , y : - x , lambda x , y : x / y , 0 ) # -> Ok(-6)
454- .apply_or_else (lambda x , y : x + 11 , lambda x , y : x / y , 2 ) # -> Ok(-3)
455- )
456-
457- assert a .is_Ok and a == Ok (5 )
458- assert b .is_Err and b .Err_msg_contains ("ValueError" )
459- assert c .is_Ok and c == Ok (None )
460- assert d .is_Ok and d == Ok (5 )
461- assert e .is_Err and e .Err_msg_contains ("ZeroDivisionError" )
462- assert f .is_Ok and f == Ok (14 )
463- assert g .is_Ok and g == Ok (- 3 )
464-
465-
466337# Arithmetic Operator Overloading
467338def test_addition ():
468339 result1 = Ok (10 )
@@ -556,12 +427,6 @@ def test_error_message_integrity():
556427 result .raises ()
557428
558429
559- def test_error_chaining_integrity ():
560- error_result = Err ("Initial Error" )
561- chained_result = error_result .map (lambda x : x * 2 ).map_Err (lambda e : f"{ e .str ()} - chained" )
562- assert chained_result .is_Err is False # map_Err returns Ok(f(e))
563-
564-
565430# Integration Tests
566431def test_real_world_scenario ():
567432 def divide (a , b ):
0 commit comments