| 1 | %%% Copyright (c) Dominic Williams, Nicolas Charpentier, Virgile Delecolle. |
|---|
| 2 | %%% All rights reserved. |
|---|
| 3 | %%% See file COPYING. |
|---|
| 4 | |
|---|
| 5 | -module (fixtures_test). |
|---|
| 6 | -test (exports). |
|---|
| 7 | -export ([temporary_pathname/0]). |
|---|
| 8 | -export ([tree_handling/0]). |
|---|
| 9 | -export ([use_tree_creates_the_tree_first_and_destroys_it_after/0]). |
|---|
| 10 | -export ([use_tree_passes_a_tree_to_a_fun/0]). |
|---|
| 11 | -export ([use_tree_destroys_tree_even_if_fun_crashes/0]). |
|---|
| 12 | -export ([use_tree_destroys_tree_even_if_trapexit/0]). |
|---|
| 13 | -export ([use_tree_destroys_tree_even_if_killed_by_parent_link/0]). |
|---|
| 14 | -export ([make_tree_accepts_single_character_content/0]). |
|---|
| 15 | |
|---|
| 16 | temporary_pathname () -> |
|---|
| 17 | Name = fixtures: temporary_pathname (), |
|---|
| 18 | true = is_list (Name), |
|---|
| 19 | {error, enoent} = file: read_file_info (Name), |
|---|
| 20 | Next_name = fixtures: temporary_pathname (), |
|---|
| 21 | false = string: equal (Name, Next_name), |
|---|
| 22 | ok = file: make_dir (Name), |
|---|
| 23 | ok = file: del_dir (Name), |
|---|
| 24 | ok = file: write_file (Next_name, list_to_binary ("Hello world")), |
|---|
| 25 | ok = file: delete (Next_name), |
|---|
| 26 | pass. |
|---|
| 27 | |
|---|
| 28 | tree () -> |
|---|
| 29 | [{file, "test", "Hello world"}, |
|---|
| 30 | {file, "test2", ["Goodbye", "world!"]}, |
|---|
| 31 | {directory, "testdir", |
|---|
| 32 | [{file, "toto", "Silly"}, |
|---|
| 33 | {directory, "testdir2", [{file, "titi", "Very silly"}]}]}]. |
|---|
| 34 | |
|---|
| 35 | test_tree (Dir) -> |
|---|
| 36 | fun ({Path, Expected}, Count) -> |
|---|
| 37 | Filename = filename: join ([Dir | Path]), |
|---|
| 38 | {ok, Content} = file: read_file (Filename), |
|---|
| 39 | {Count, Expected} = {Count, binary_to_list (Content)}, |
|---|
| 40 | Count + 1 |
|---|
| 41 | end. |
|---|
| 42 | |
|---|
| 43 | tree_handling () -> |
|---|
| 44 | Tmp_dirname = fixtures: temporary_pathname(), |
|---|
| 45 | Tree = tree (), |
|---|
| 46 | fixtures: make_tree (Tmp_dirname, Tree), |
|---|
| 47 | Test = test_tree (Tmp_dirname), |
|---|
| 48 | Table = |
|---|
| 49 | [{["test"], "Hello world"}, |
|---|
| 50 | {["test2"], "Goodbye\nworld!"}, |
|---|
| 51 | {["testdir", "toto"], "Silly"}, |
|---|
| 52 | {["testdir", "testdir2", "titi"], "Very silly"}], |
|---|
| 53 | lists: foldl (Test, 1, Table), |
|---|
| 54 | fixtures: delete_tree (Tmp_dirname), |
|---|
| 55 | {error, enoent} = file: read_file_info (Tmp_dirname), |
|---|
| 56 | pass. |
|---|
| 57 | |
|---|
| 58 | make_tree_accepts_single_character_content () -> |
|---|
| 59 | Tmp_dirname = fixtures: temporary_pathname(), |
|---|
| 60 | Tree = [{file, "myfile", "a"}], |
|---|
| 61 | ok = fixtures: make_tree (Tmp_dirname, Tree), |
|---|
| 62 | {ok, B} = file: read_file (filename: join (Tmp_dirname, "myfile")), |
|---|
| 63 | "a" = binary_to_list (B), |
|---|
| 64 | fixtures: delete_tree (Tmp_dirname), |
|---|
| 65 | pass. |
|---|
| 66 | |
|---|
| 67 | use_tree_passes_a_tree_to_a_fun () -> |
|---|
| 68 | Tmp = fixtures: temporary_pathname (), |
|---|
| 69 | Tree = tree (), |
|---|
| 70 | Ref = make_ref (), |
|---|
| 71 | No_op = fun (D, T) when D == Tmp, T == Tree-> Ref end, |
|---|
| 72 | Ref = fixtures: use_tree (Tmp, Tree, No_op), |
|---|
| 73 | {error,enoent} = file: read_file_info (Tmp), |
|---|
| 74 | pass. |
|---|
| 75 | |
|---|
| 76 | use_tree_creates_the_tree_first_and_destroys_it_after () -> |
|---|
| 77 | Tmp = fixtures: temporary_pathname (), |
|---|
| 78 | Result = fixtures: use_tree (Tmp, tree (), fun keep_real_files/2), |
|---|
| 79 | ["test", "test2", "testdir"] = Result, |
|---|
| 80 | {error,enoent} = file: read_file_info (Tmp), |
|---|
| 81 | pass. |
|---|
| 82 | |
|---|
| 83 | keep_real_files (Dir, Tree) -> |
|---|
| 84 | [X || {_,X,_} <- Tree, filelib: is_file (filename: join (Dir, X))]. |
|---|
| 85 | |
|---|
| 86 | use_tree_destroys_tree_even_if_fun_crashes () -> |
|---|
| 87 | Tmp = fixtures: temporary_pathname (), |
|---|
| 88 | Tree = tree (), |
|---|
| 89 | ok = |
|---|
| 90 | try |
|---|
| 91 | fixtures: use_tree (Tmp, Tree, fun suicide/2), |
|---|
| 92 | no_crash |
|---|
| 93 | catch |
|---|
| 94 | _: {suicide, Tmp, Tree} -> ok; |
|---|
| 95 | C: E -> {unexpected, C, E} |
|---|
| 96 | end, |
|---|
| 97 | {error, enoent} = file: read_file_info (Tmp), |
|---|
| 98 | pass. |
|---|
| 99 | |
|---|
| 100 | spawn_undef (_, _) -> |
|---|
| 101 | spawn_link (blabla, blabla, []), |
|---|
| 102 | receive M -> M end. |
|---|
| 103 | |
|---|
| 104 | use_tree_destroys_tree_even_if_trapexit () -> |
|---|
| 105 | Tmp = fixtures: temporary_pathname (), |
|---|
| 106 | ok = |
|---|
| 107 | try |
|---|
| 108 | fixtures: use_tree (Tmp, [], fun spawn_undef/2), |
|---|
| 109 | no_crash |
|---|
| 110 | catch |
|---|
| 111 | _: {undef, _} -> ok; |
|---|
| 112 | C:E -> {unexpected, C, E} |
|---|
| 113 | end, |
|---|
| 114 | {error, enoent} = file: read_file_info (Tmp), |
|---|
| 115 | pass. |
|---|
| 116 | |
|---|
| 117 | suicide (Dir, Tree) -> |
|---|
| 118 | exit ({suicide, Dir, Tree}). |
|---|
| 119 | |
|---|
| 120 | use_tree_destroys_tree_even_if_killed_by_parent_link () -> |
|---|
| 121 | Tmp = fixtures: temporary_pathname (), |
|---|
| 122 | Self = self (), |
|---|
| 123 | ok = |
|---|
| 124 | try |
|---|
| 125 | Long = fun (_, _) -> Self ! tree_built, timer: sleep (5000) end, |
|---|
| 126 | Use_tree = fun () -> fixtures: use_tree (Tmp, [], Long) end, |
|---|
| 127 | Impatient = fun () -> spawn_link (Use_tree), |
|---|
| 128 | receive tree_built -> ok end, |
|---|
| 129 | throw (stop) end, |
|---|
| 130 | Pid = spawn (Impatient), |
|---|
| 131 | receive tree_built -> Pid ! tree_built end, |
|---|
| 132 | ok |
|---|
| 133 | catch |
|---|
| 134 | C: E -> {unexpected, C, E} |
|---|
| 135 | end, |
|---|
| 136 | timer: sleep (500), |
|---|
| 137 | {error, enoent} = file: read_file_info (Tmp), |
|---|
| 138 | pass. |
|---|