@@ -257,7 +257,7 @@ let get_snapshot_path (test : T.test) default_name
257257
258258let get_file_snapshot_path (test : T.test ) (x : T.checked_output_file ) =
259259 match x.options.snapshot_path with
260- | None -> get_expectation_workspace () / test.id / x.name
260+ | None -> get_expectation_workspace () / test.id / ( " file- " ^ x.name)
261261 | Some path -> path
262262
263263let short_name_of_checked_output_options default_name
@@ -298,71 +298,57 @@ let capture_paths_of_test (test : T.test) : capture_paths list =
298298 path_to_output = get_output_path test unchecked_filename;
299299 }
300300 in
301- let std_output_paths =
302- match test.checked_output with
303- | Ignore_output -> [ unchecked_paths ]
304- | Stdout options ->
305- [
306- {
307- short_name =
308- short_name_of_checked_output_options stdout_filename options;
309- path_to_expected_output =
310- Some (get_snapshot_path test stdout_filename options);
311- path_to_output = get_output_path test stdout_filename;
312- };
313- unchecked_paths;
314- ]
315- | Stderr options ->
316- [
317- {
318- short_name =
319- short_name_of_checked_output_options stderr_filename options;
320- path_to_expected_output =
321- Some (get_snapshot_path test stderr_filename options);
322- path_to_output = get_output_path test stderr_filename;
323- };
324- unchecked_paths;
325- ]
326- | Stdxxx options ->
327- [
328- {
329- short_name =
330- short_name_of_checked_output_options stdxxx_filename options;
331- path_to_expected_output =
332- Some (get_snapshot_path test stdxxx_filename options);
333- path_to_output = get_output_path test stdxxx_filename;
334- };
335- ]
336- | Split_stdout_stderr (stdout_options , stderr_options ) ->
337- [
338- {
339- short_name =
340- short_name_of_checked_output_options stdout_filename stdout_options;
341- path_to_expected_output =
342- Some (get_snapshot_path test stdout_filename stdout_options);
343- path_to_output = get_output_path test stdout_filename;
344- };
345- {
346- short_name =
347- short_name_of_checked_output_options stderr_filename stderr_options;
348- path_to_expected_output =
349- Some (get_snapshot_path test stderr_filename stderr_options);
350- path_to_output = get_output_path test stderr_filename;
351- };
352- ]
353- in
354- let output_file_paths =
355- test.checked_output_files
356- |> Helpers. list_map (fun (x : T.checked_output_file ) ->
357- {
358- short_name = x.name;
359- path_to_expected_output =
360- Some (get_file_snapshot_path test x);
361- path_to_output = get_output_file_path test x;
362- }
363- )
364- in
365- std_output_paths @ output_file_paths
301+ match test.checked_output with
302+ | Ignore_output -> [ unchecked_paths ]
303+ | Stdout options ->
304+ [
305+ {
306+ short_name =
307+ short_name_of_checked_output_options stdout_filename options;
308+ path_to_expected_output =
309+ Some (get_snapshot_path test stdout_filename options);
310+ path_to_output = get_output_path test stdout_filename;
311+ };
312+ unchecked_paths;
313+ ]
314+ | Stderr options ->
315+ [
316+ {
317+ short_name =
318+ short_name_of_checked_output_options stderr_filename options;
319+ path_to_expected_output =
320+ Some (get_snapshot_path test stderr_filename options);
321+ path_to_output = get_output_path test stderr_filename;
322+ };
323+ unchecked_paths;
324+ ]
325+ | Stdxxx options ->
326+ [
327+ {
328+ short_name =
329+ short_name_of_checked_output_options stdxxx_filename options;
330+ path_to_expected_output =
331+ Some (get_snapshot_path test stdxxx_filename options);
332+ path_to_output = get_output_path test stdxxx_filename;
333+ };
334+ ]
335+ | Split_stdout_stderr (stdout_options , stderr_options ) ->
336+ [
337+ {
338+ short_name =
339+ short_name_of_checked_output_options stdout_filename stdout_options;
340+ path_to_expected_output =
341+ Some (get_snapshot_path test stdout_filename stdout_options);
342+ path_to_output = get_output_path test stdout_filename;
343+ };
344+ {
345+ short_name =
346+ short_name_of_checked_output_options stderr_filename stderr_options;
347+ path_to_expected_output =
348+ Some (get_snapshot_path test stderr_filename stderr_options);
349+ path_to_output = get_output_path test stderr_filename;
350+ };
351+ ]
366352
367353let describe_unchecked_output (output : T.checked_output_kind ) : string option =
368354 match output with
@@ -419,7 +405,11 @@ let set_expected_output (test : T.test) (capture_paths : capture_paths list)
419405
420406let clear_expected_output (test : T.test ) =
421407 test |> capture_paths_of_test
422- |> List. iter (fun x -> Option. iter remove_file x.path_to_expected_output)
408+ |> List. iter (fun x -> Option. iter remove_file x.path_to_expected_output);
409+ test.checked_output_files
410+ |> List. iter (fun (x : T.checked_output_file ) ->
411+ remove_file (get_file_snapshot_path test x)
412+ )
423413
424414let read_name_file ~dir =
425415 let name_file_path = get_name_file_path_from_dir dir in
@@ -644,6 +634,12 @@ let stash_output_file (test : T.test) (x : T.checked_output_file) : unit =
644634 let dst = get_output_file_path test x in
645635 Helpers. copy_file src dst
646636
637+ let remove_stashed_output_files (test : T.test ) =
638+ test.checked_output_files
639+ |> List. iter (fun (x : T.checked_output_file ) ->
640+ remove_file (get_output_file_path test x)
641+ )
642+
647643(* *************************************************************************)
648644(* High-level interface *)
649645(* *************************************************************************)
@@ -679,20 +675,52 @@ let get_expectation (test : T.test) (paths : capture_paths list) : T.expectation
679675 | Ok x -> Ok (expected_output_of_data test.checked_output x)
680676 | Error missing_files -> Error (T. Missing_files missing_files)
681677 in
682- { expected_outcome = test.expected_outcome; expected_output }
678+ let expected_output_files =
679+ test.checked_output_files
680+ |> Helpers. list_map (fun (checked_file : T.checked_output_file ) ->
681+ match read_file (get_file_snapshot_path test checked_file) with
682+ | Ok contents ->
683+ Ok ({ checked_file; contents } : T.checked_output_file_with_contents )
684+ | Error _path ->
685+ Error checked_file
686+ )
687+ in
688+ { expected_outcome = test.expected_outcome;
689+ expected_output;
690+ expected_output_files }
683691
692+ (* Fail if any capture file is missing *)
684693let get_result (test : T.test ) (paths : capture_paths list ) :
685694 (T. result , T. missing_files ) Result. t =
686695 match get_completion_status test with
687696 | Error missing_file -> Error (Missing_files [ missing_file ])
688697 | Ok completion_status -> (
698+ (* captured output files *)
699+ let captured_output_files, missing_output_files =
700+ test.checked_output_files
701+ |> Helpers. list_map (fun (checked_file : T.checked_output_file ) ->
702+ match read_file (get_output_file_path test checked_file) with
703+ | Ok contents ->
704+ Ok ({ checked_file; contents } : T.checked_output_file_with_contents )
705+ | Error missing_file -> Error missing_file
706+ )
707+ |> Helpers. split_result_list
708+ in
709+ (* captured standard output *)
689710 let opt_captured_output =
690711 paths |> get_output |> list_result_of_result_list
691712 |> Result. map (captured_output_of_data test.checked_output)
692713 in
693- match opt_captured_output with
694- | Error missing_files -> Error (Missing_files missing_files)
695- | Ok captured_output -> Ok { completion_status; captured_output })
714+ match opt_captured_output, missing_output_files with
715+ | Ok captured_output , [] ->
716+ Ok { completion_status;
717+ captured_output;
718+ captured_output_files }
719+ | Ok _ , missing_output_files ->
720+ Error (Missing_files missing_output_files)
721+ | Error missing_std_files , missing_output_files ->
722+ Error (Missing_files (missing_std_files @ missing_output_files))
723+ )
696724
697725let get_status (test : T.test ) : T.status =
698726 let paths = capture_paths_of_test test in
@@ -716,13 +744,33 @@ let outcome_of_expectation_and_result
716744 (expect : T.expectation ) (result : T.result )
717745 : T.outcome * bool =
718746 let has_expected_output, output_matches =
719- match ( expect.expected_output, result.captured_output) with
747+ match expect.expected_output, result.captured_output with
720748 | Ok output1 , output2 when T. equal_checked_output output1 output2 ->
721749 (true , true )
722750 | Ok _ , _ -> (true , false )
723751 | Error _ , _ -> (false , true )
724752 in
725- outcome_of_pair result.completion_status output_matches, has_expected_output
753+ let has_expected_output_files, output_files_match =
754+ (* Assume the lists of expected files and captured files are complete
755+ and in the same order. *)
756+ List. fold_left2 (
757+ fun
758+ (has_expected_output_files , output_files_match )
759+ (expect : (T.checked_output_file_with_contents, T.checked_output_file) Result.t )
760+ (result : T.checked_output_file_with_contents ) ->
761+ match expect with
762+ | Ok expected ->
763+ assert (expected.checked_file = result.checked_file);
764+ if expected.contents = result.contents then
765+ has_expected_output_files, output_files_match
766+ else
767+ has_expected_output_files, false
768+ | Error missing_expected_file ->
769+ assert (missing_expected_file = result.checked_file);
770+ false , false
771+ ) (true , true ) expect.expected_output_files result.captured_output_files
772+ in
773+ outcome_of_pair result.completion_status (output_matches && output_files_match), (has_expected_output && has_expected_output_files)
726774
727775let status_summary_of_status (status : T.status ) : T.status_summary =
728776 match status.result with
@@ -771,6 +819,7 @@ type changed = Changed | Unchanged
771819
772820exception Local_error of string
773821
822+ (* TODO: approve the captured output files *)
774823let approve_new_output (test : T.test ) : (changed, string) Result.t =
775824 match test.skipped with
776825 | Some _reason -> Ok Unchanged
0 commit comments