v2 / vlib / v / tests / defer / scoped_defer_test.v
143 lines · 128 sloc · 1.92 KB · 29bef1dc81247a99285c363b8f966cc8edb99bc2
Raw
1struct Data {
2mut:
3 counter int
4}
5
6fn (mut d Data) operation(fail bool) !int {
7 if fail {
8 return error('')
9 }
10 return 10
11}
12
13fn (mut d Data) run_operation(fail bool) !int {
14 return d.operation(fail) or {
15 defer {
16 d.counter++
17 }
18 err
19 }
20}
21
22fn test_defer_with_or_expr() {
23 mut d := Data{}
24 d.run_operation(true) or {}
25 assert d.counter == 1
26
27 d.run_operation(false) or {}
28 assert d.counter == 1
29
30 d.run_operation(true) or {}
31 assert d.counter == 2
32}
33
34fn some() !int {
35 return 5
36}
37
38fn test_if_expr_with_defer() {
39 mut abc := 0
40 x := if v := some() {
41 defer { assert abc == 9090 }
42 defer { abc = 9090 }
43 v
44 } else {
45 2004
46 }
47 assert x == 5
48}
49
50fn test_scoped_defer() {
51 mut res := 0
52
53 defer {
54 res++
55 assert res == 5
56 }
57 {
58 res++
59 defer {
60 res++
61 assert res == 4
62 }
63 {
64 res++
65 defer {
66 res++
67 assert res == 3
68 }
69 } // <- Block 2 ends. Defer 3 executes. res = 3.
70 } // <- Block 1 ends. Defer 2 executes. res = 4.
71} // <- 'test_scoped_defer' ends. Defer 1 executes. res = 5.
72
73fn test_defer_with_comptime_if() {
74 mut c := 0
75 defer { assert c == 3 }
76 defer { c++ }
77 $if tinyc || gcc || clang || msvc || mingw {
78 defer { c++ }
79 c++
80 } $else {
81 c = 0
82 }
83}
84
85fn test_defer_with_comptime_match() {
86 mut c := 0
87 defer { assert c == 3 }
88 defer { c++ }
89 $match @CCOMPILER {
90 'tinyc', 'gcc', 'clang', 'msvc', 'mingw' {
91 defer { c++ }
92 c++
93 }
94 $else {
95 c = 0
96 }
97 }
98}
99
100fn test_defer_with_comptime_for() {
101 mut c := 0
102 $for f in Data.fields {
103 defer {
104 if f.name == 'counter' {
105 c++
106 }
107 }
108 }
109 assert c == 1
110
111 $for m in Data.methods {
112 defer {
113 if m.name in ['operation', 'run_operation'] {
114 c++
115 }
116 }
117 }
118 assert c == 3
119}
120
121fn test_defer_fn_with_inner_var() {
122 mut x := 0
123 defer {
124 assert x == 1
125 }
126 {
127 a := 1
128 defer(fn) {
129 x = a
130 }
131 }
132}
133
134fn test_scoped_defer_can_use_inner_var_declared_in_loop() {
135 mut values := []int{}
136 for i := 0; i < 3; i++ {
137 defer {
138 j := i
139 values << j
140 }
141 }
142 assert values == [0, 1, 2]
143}
144