v2 / vlib / v / tests / assert_short_circuit_test.v
70 lines · 63 sloc · 1.99 KB · da858a903d78c1474b37bc7022b3be9ace232525
Raw
1// Test for issue #26777: assert with || and && should properly short-circuit
2module main
3
4struct Node {
5 name string
6mut:
7 parent &Node = unsafe { nil }
8 children []Node
9}
10
11fn test_assert_or_short_circuit_with_nil_parent() {
12 mut p := Node{
13 name: 'abc'
14 }
15 // This should work - the right side of || should not be evaluated
16 // when the left side is true (p.parent == nil)
17 assert unsafe { p.parent == nil } || !p.parent.children.any(it.name == p.name)
18 assert true
19}
20
21fn test_assert_and_short_circuit_with_nil_parent() {
22 mut p := Node{
23 name: 'abc'
24 }
25 // Test &&: when left is true, right should be evaluated (non-short-circuit path)
26 // This tests that the right side IS evaluated when left is true
27 assert true && p.name == 'abc'
28 // Test && short-circuit: left is false, right should NOT be evaluated
29 // With fix, right is short-circuited (no nil access)
30 // Without fix, would crash with nil pointer access
31 // We use a simple bool expr to avoid assert failure
32 _ = false && unsafe { p.parent == nil }
33}
34
35fn test_assert_or_with_message() {
36 mut p := Node{
37 name: 'abc'
38 }
39 // This should work with a message too
40 assert unsafe { p.parent == nil } || !p.parent.children.any(it.name == p.name), 'parent check failed'
41 assert true
42}
43
44fn test_assert_or_both_sides_need_eval() {
45 mut child := Node{
46 name: 'child'
47 }
48 // child.parent is nil by default
49 // Left side is false (child.parent == nil, so child.parent != nil is false)
50 // Right side must be evaluated - use a simple true to test both sides are evaluated
51 assert unsafe { child.parent != nil } || true, 'should evaluate both sides'
52}
53
54fn test_nested_or_in_assert() {
55 mut p := Node{
56 name: 'test'
57 }
58 // Nested unsafe block with ||
59 assert unsafe { p.parent == nil } || unsafe { p.parent != nil }
60 assert true
61}
62
63fn main() {
64 test_assert_or_short_circuit_with_nil_parent()
65 test_assert_and_short_circuit_with_nil_parent()
66 test_assert_or_with_message()
67 test_assert_or_both_sides_need_eval()
68 test_nested_or_in_assert()
69 println('All short-circuit tests passed!')
70}
71