@@ -28,6 +28,9 @@ defmodule ExUnit.CaptureIO do
28
28
named device like `:stderr` is also possible globally by
29
29
giving the registered device name explicitly as argument.
30
30
31
+ When capturing of `:stdio`, this function captures a prompt,
32
+ otherwise do not.
33
+
31
34
A developer can set a string as an input. The default
32
35
input is `:eof`.
33
36
@@ -40,9 +43,9 @@ defmodule ExUnit.CaptureIO do
40
43
iex> capture_io(:stderr, fn -> IO.write(:stderr, "josé") end) == "josé"
41
44
true
42
45
iex> capture_io("this is input", fn->
43
- ...> input = IO.gets ""
46
+ ...> input = IO.gets "> "
44
47
...> IO.write input
45
- ...> end) == "this is input"
48
+ ...> end) == "> this is input"
46
49
true
47
50
48
51
"""
@@ -68,7 +71,7 @@ defmodule ExUnit.CaptureIO do
68
71
69
72
defp do_capture_io ( :standard_io , input , fun ) do
70
73
original_gl = :erlang . group_leader
71
- capture_gl = new_group_leader ( self , input )
74
+ capture_gl = new_group_leader ( self , input , true )
72
75
:erlang . group_leader ( capture_gl , self )
73
76
74
77
try do
@@ -105,12 +108,13 @@ defmodule ExUnit.CaptureIO do
105
108
end
106
109
end
107
110
108
- defp new_group_leader ( runner , input ) do
109
- spawn_link ( fn -> group_leader_process ( runner , input ) end )
111
+ defp new_group_leader ( runner , input , prompt_config // false ) do
112
+ spawn_link ( fn -> group_leader_process ( runner , input , prompt_config ) end )
110
113
end
111
114
112
- defp group_leader_process ( runner , input ) do
115
+ defp group_leader_process ( runner , input , prompt_config ) do
113
116
register_input ( input )
117
+ register_prompt_config ( prompt_config )
114
118
group_leader_loop ( runner , :infinity , [ ] )
115
119
end
116
120
@@ -123,6 +127,10 @@ defmodule ExUnit.CaptureIO do
123
127
set_input ( chars )
124
128
end
125
129
130
+ defp register_prompt_config ( bool ) do
131
+ Process . put ( :capture_io_prompt_config , bool )
132
+ end
133
+
126
134
defp set_input ( :eof ) do
127
135
set_input ( [ ] )
128
136
end
@@ -135,6 +143,10 @@ defmodule ExUnit.CaptureIO do
135
143
Process . get ( :capture_io_input )
136
144
end
137
145
146
+ defp need_prompt? do
147
+ Process . get ( :capture_io_prompt_config )
148
+ end
149
+
138
150
defp group_leader_loop ( runner , wait , buf ) do
139
151
receive do
140
152
{ :io_request , from , reply_as , req } ->
@@ -181,28 +193,42 @@ defmodule ExUnit.CaptureIO do
181
193
io_request ( { :put_chars , mod , func , args } , buf )
182
194
end
183
195
184
- defp io_request ( { :get_chars , _enc , _prompt , n } , buf ) when n >= 0 do
185
- { get_chars ( n ) , buf }
196
+ defp io_request ( { :get_chars , _enc , prompt , n } , buf ) when n >= 0 do
197
+ io_request ( { : get_chars, prompt , n } , buf )
186
198
end
187
199
188
- defp io_request ( { :get_chars , _prompt , n } , buf ) when n >= 0 do
200
+ defp io_request ( { :get_chars , prompt , n } , buf ) when n >= 0 do
201
+ if need_prompt? do
202
+ buf = [ prompt | buf ]
203
+ end
204
+
189
205
{ get_chars ( n ) , buf }
190
206
end
191
207
192
- defp io_request ( { :get_line , _prompt } , buf ) do
193
- { get_line , buf }
208
+ defp io_request ( { :get_line , _enc , prompt } , buf ) do
209
+ io_request ( { : get_line, prompt } , buf )
194
210
end
195
211
196
- defp io_request ( { :get_line , _enc , _prompt } , buf ) do
212
+ defp io_request ( { :get_line , prompt } , buf ) do
213
+ if need_prompt? do
214
+ buf = [ prompt | buf ]
215
+ end
216
+
197
217
{ get_line , buf }
198
218
end
199
219
200
- defp io_request ( { :get_until , _prompt , mod , fun , args } , buf ) do
201
- { get_until ( mod , fun , args ) , buf }
220
+ defp io_request ( { :get_until , _encoding , prompt , mod , fun , args } , buf ) do
221
+ io_request ( { : get_until, prompt , mod , fun , args } , buf )
202
222
end
203
223
204
- defp io_request ( { :get_until , _encoding , _prompt , mod , fun , args } , buf ) do
205
- { get_until ( mod , fun , args ) , buf }
224
+ defp io_request ( { :get_until , prompt , mod , fun , args } , buf ) do
225
+ { result , count } = get_until ( mod , fun , args )
226
+
227
+ if need_prompt? do
228
+ buf = [ :lists . duplicate ( count , prompt ) | buf ]
229
+ end
230
+
231
+ { result , buf }
206
232
end
207
233
208
234
defp io_request ( { :setopts , _opts } , buf ) do
@@ -274,37 +300,37 @@ defmodule ExUnit.CaptureIO do
274
300
do_get_until ( input , mod , fun , args )
275
301
end
276
302
277
- defp do_get_until ( [ ] , mod , fun , args , continuation // [ ] )
303
+ defp do_get_until ( [ ] , mod , fun , args , continuation // [ ] , count // 0 )
278
304
279
- defp do_get_until ( [ ] , mod , fun , args , continuation ) do
305
+ defp do_get_until ( [ ] , mod , fun , args , continuation , count ) do
280
306
case apply ( mod , fun , [ continuation , :eof | args ] ) do
281
307
{ :done , result , rest_chars } ->
282
308
set_input ( rest_chars )
283
- result
309
+ { result , count + 1 }
284
310
{ :more , next_continuation } ->
285
- do_get_until ( [ ] , mod , fun , args , next_continuation )
311
+ do_get_until ( [ ] , mod , fun , args , next_continuation , count + 1 )
286
312
end
287
313
end
288
314
289
- defp do_get_until ( input , mod , fun , args , continuation ) do
315
+ defp do_get_until ( input , mod , fun , args , continuation , count ) do
290
316
{ line , rest } = Enum . split_while ( input , fn ( char ) -> char != ?\n end )
291
317
292
318
case rest do
293
319
[ ] ->
294
320
case apply ( mod , fun , [ continuation , line | args ] ) do
295
321
{ :done , result , rest_chars } ->
296
322
set_input ( rest_chars )
297
- result
323
+ { result , count + 1 }
298
324
{ :more , next_continuation } ->
299
- do_get_until ( [ ] , mod , fun , args , next_continuation )
325
+ do_get_until ( [ ] , mod , fun , args , next_continuation , count + 1 )
300
326
end
301
327
[ _ | t ] ->
302
328
case apply ( mod , fun , [ continuation , line ++ '\n ' | args ] ) do
303
329
{ :done , result , rest_chars } ->
304
330
set_input ( rest_chars ++ t )
305
- result
331
+ { result , count + 1 }
306
332
{ :more , next_continuation } ->
307
- do_get_until ( t , mod , fun , args , next_continuation )
333
+ do_get_until ( t , mod , fun , args , next_continuation , count + 1 )
308
334
end
309
335
end
310
336
end
0 commit comments