| 1 | import os |
| 2 | import rand |
| 3 | import test_utils |
| 4 | |
| 5 | const vexe = os.quoted_path(@VEXE) |
| 6 | const test_path = os.join_path(os.vtmp_dir(), 'vpm_link_test_${rand.ulid()}') |
| 7 | |
| 8 | fn testsuite_begin() { |
| 9 | test_utils.set_test_env(test_path) |
| 10 | os.mkdir_all(test_path) or {} |
| 11 | } |
| 12 | |
| 13 | fn testsuite_end() { |
| 14 | os.rmdir_all(test_path) or {} |
| 15 | } |
| 16 | |
| 17 | fn execute_in_dir(dir string, cmd string) os.Result { |
| 18 | old_dir := os.getwd() |
| 19 | os.chdir(dir) or { return os.Result{ |
| 20 | exit_code: -1 |
| 21 | output: 'failed to chdir: ${err}' |
| 22 | } } |
| 23 | defer { |
| 24 | os.chdir(old_dir) or {} |
| 25 | } |
| 26 | return os.execute(cmd) |
| 27 | } |
| 28 | |
| 29 | fn test_link_and_unlink_current_project() { |
| 30 | module_name := 'author.coollib' |
| 31 | project_path := os.join_path(test_path, 'project') |
| 32 | write_vmod(project_path, module_name) or { |
| 33 | assert false, err.msg() |
| 34 | return |
| 35 | } |
| 36 | project_subdir := os.join_path(project_path, 'src') |
| 37 | os.mkdir_all(project_subdir) or { |
| 38 | assert false, err.msg() |
| 39 | return |
| 40 | } |
| 41 | link_path := os.join_path(test_path, 'author', 'coollib') |
| 42 | |
| 43 | link_res := execute_in_dir(project_subdir, '${vexe} link') |
| 44 | if link_res.exit_code != 0 && is_symlink_privilege_error(link_res.output) { |
| 45 | eprintln('Skipping symlink test due to missing privileges.') |
| 46 | return |
| 47 | } |
| 48 | assert link_res.exit_code == 0, link_res.output |
| 49 | assert os.is_link(link_path), 'expected `${link_path}` to be a symlink' |
| 50 | assert os.real_path(link_path) == os.real_path(project_path) |
| 51 | assert link_res.output.contains('Linked `${module_name}`'), link_res.output |
| 52 | |
| 53 | link_again_res := execute_in_dir(project_path, '${vexe} link') |
| 54 | assert link_again_res.exit_code == 0, link_again_res.output |
| 55 | assert link_again_res.output.contains('already linked') |
| 56 | || link_again_res.output.contains('already available'), link_again_res.output |
| 57 | |
| 58 | unlink_res := execute_in_dir(project_subdir, '${vexe} unlink') |
| 59 | assert unlink_res.exit_code == 0, unlink_res.output |
| 60 | assert !os.exists(link_path) && !os.is_link(link_path) |
| 61 | assert !os.exists(os.join_path(test_path, 'author')) |
| 62 | assert unlink_res.output.contains('Unlinked `${module_name}`'), unlink_res.output |
| 63 | } |
| 64 | |
| 65 | fn test_link_without_vmod() { |
| 66 | path := os.join_path(test_path, 'no_manifest') |
| 67 | os.mkdir_all(path) or { |
| 68 | assert false, err.msg() |
| 69 | return |
| 70 | } |
| 71 | res := execute_in_dir(path, '${vexe} link') |
| 72 | assert res.exit_code == 1, res.output |
| 73 | assert res.output.contains('no `v.mod` file found'), res.output |
| 74 | } |
| 75 | |
| 76 | fn write_vmod(path string, module_name string) ! { |
| 77 | os.mkdir_all(path)! |
| 78 | vmod_path := os.join_path(path, 'v.mod') |
| 79 | vmod_contents := "Module {\n\tname: '${module_name}'\n\tdescription: ''\n\tversion: '0.0.0'\n\tlicense: 'MIT'\n\tdependencies: []\n}\n" |
| 80 | os.write_file(vmod_path, vmod_contents)! |
| 81 | } |
| 82 | |
| 83 | fn is_symlink_privilege_error(output string) bool { |
| 84 | lower := output.to_lower() |
| 85 | return lower.contains('required privilege is not held') || lower.contains('symbolic link') |
| 86 | } |
| 87 | |