@@ -120,27 +120,44 @@ define function next-indent () => (indent :: <string>)
120120 concatenate (*indent*, $indent-step)
121121end function ;
122122
123- // Return a temporary directory unique to the current test or benchmark. The
124- // directory is created the first time this is called for a given test.
125- // The directory is _test/<user>-<yyyymmdd-hhmmss>/<full-test-name>/, relative
126- // to ${DYLAN}/, if defined, or relative to fs/working-directory() otherwise.
123+ define function default-runner-temp-directory () => (dir :: <directory-locator>)
124+ let dylan = os/environment-variable("DYLAN" );
125+ let base = if (dylan)
126+ as (<directory-locator>, dylan)
127+ else
128+ fs/working-directory()
129+ end ;
130+ let dated-dir
131+ = concatenate (os/login-name() | "unknown" ,
132+ "-" ,
133+ date/format("%Y%m%d-%H%M%S" , date/now()));
134+ // We could just include milliseconds (%F) in the date format below but currently
135+ // <date> milliseconds are always zero, at least on Unix.
136+ // https://github.com/dylan-lang/testworks/issues/199
137+ iterate loop (i = 1 )
138+ let uniquifier = format-to-string("%s.%d" , dated-dir, i);
139+ let dir = subdirectory-locator(base, "_test" , uniquifier);
140+ if (block ()
141+ fs/file-exists?(dir)
142+ exception (ex :: fs/<file-system-error>)
143+ #f
144+ end )
145+ loop(i + 1 )
146+ else
147+ dir
148+ end
149+ end
150+ end function ;
151+
152+ // Return a temporary directory unique to the current test or benchmark.
127153define function test-temp-directory () => (d :: false-or (<directory-locator>))
128154 if (instance? (*component*, <runnable>))
129- let dylan = os/environment-variable("DYLAN" );
130- let base = if (dylan)
131- as (<directory-locator>, dylan)
132- else
133- fs/working-directory()
134- end ;
135- let uniquifier
136- = format-to-string("%s-%s" , os/login-name() | "unknown" ,
137- date/format("%Y%m%d-%H%M%S" , date/now()));
138155 let safe-name = map (method (c)
139156 if (c == '\\' | c == '/' ) '_' else c end
140157 end ,
141158 component-name(*component*));
142159 let test-directory
143- = subdirectory-locator(base, "_test" , uniquifier , safe-name);
160+ = subdirectory-locator(runner-temp-directory(*runner*) , safe-name);
144161 fs/ensure-directories-exist(test-directory);
145162 test-directory
146163 end
@@ -165,9 +182,8 @@ define function write-test-file
165182 locator
166183end function ;
167184
168- // For tests to do debugging output.
169- // TODO(cgay): Collect this and stdio into a log file per test run
170- // or per test. The Surefire report has a place for stdout, too.
185+ // For output to the main output stream for the test run. That is, this output is never
186+ // redirected to the _captured-stdout.txt file in a test's temp directory.
171187define method test-output
172188 (format-string :: <string> , #rest format-args) => ()
173189 let stream = if (*runner*)
@@ -180,3 +196,17 @@ define method test-output
180196 force-output(stream);
181197 end ;
182198end method ;
199+
200+ define constant $captured-output-filename :: <string> = "_captured-stdout.txt" ;
201+
202+ define variable *output-captured?* :: <boolean> = #f ;
203+
204+ define function write-captured-output (output :: <string> )
205+ block ()
206+ let file = file-locator(test-temp-directory(), $captured-output-filename);
207+ write-test-file(file, contents: output);
208+ *output-captured?* := #t ;
209+ exception (err :: <error> )
210+ test-output("ERROR writing to test's output file: %s\n %s\n " , err, output);
211+ end ;
212+ end function ;
0 commit comments