diff --git a/fixtures/fake-peer-dunder-tests-project/src/__tests__/app.js b/fixtures/fake-peer-dunder-tests-project/src/__tests__/app.js new file mode 100644 index 0000000..e69de29 diff --git a/fixtures/fake-peer-dunder-tests-project/src/app.js b/fixtures/fake-peer-dunder-tests-project/src/app.js new file mode 100644 index 0000000..e69de29 diff --git a/lua/go_to_test_file.lua b/lua/go_to_test_file.lua index 9feb984..89cf586 100644 --- a/lua/go_to_test_file.lua +++ b/lua/go_to_test_file.lua @@ -5,6 +5,8 @@ local root_tests = require('go_to_test_file.root_tests') local path = require('go_to_test_file.path') local system = require('go_to_test_file.system') local list = require('go_to_test_file.list') +local project = require('go_to_test_file.project') +local peer_dunder_tests = require('go_to_test_file.peer_dunder_tests') local go_to_test_file = { git = git, @@ -25,34 +27,47 @@ go_to_test_file.find_test_or_source_file = function(git_root, current_file_abs_p if peer.should_have_source_file(current_file_abs_path) then return {peer.find_source_file(current_file_abs_path), folder} else - local test_folder_path = root_tests.test_path_from_filepath(current_file_abs_path) + local test_folder_path = project.test_path_from_filepath(current_file_abs_path) + --local test_folder_path = root_tests.test_path_from_filepath(current_file_abs_path) local filename_no_ext = path.filename_no_ext(current_file_abs_path) - if test_folder_path ~= '' then + local match = list.match_one(test_folder_path, peer_dunder_tests.test_folder_names, ps, '/?$') + if match and match ~= '' then + local source_folder = path.dirname(test_folder_path) + local filename = path.basename(current_file_abs_path) + return {peer_dunder_tests.find_source_file(source_folder, filename), source_folder} + elseif test_folder_path ~= '' then local project_root = root_tests.project_root_from_test_folder(test_folder_path) local test_foldername = path.basename(test_folder_path) local test_filename_without_test_identifiers = project_generic.remove_test_file_name_identifiers(filename_no_ext) return {root_tests.find_source_file(project_root, test_foldername, test_filename_without_test_identifiers), test_folder_path} else - local peer_test_code_file = peer.find_test_file(current_file_abs_path) - if peer_test_code_file ~= '' then - return {peer_test_code_file, folder} + local source_folder = path.dirname(current_file_abs_path) + local filename = path.basename(current_file_abs_path) + local dunder_folder = peer_dunder_tests.folder_tests_folder(source_folder) + if dunder_folder ~= '' then + return {peer_dunder_tests.find_source_file(dunder_folder, filename), test_folder_path} else - local test_paths = root_tests.potential_test_folders(git_root) - local test_folder = root_tests.nearest_test_folder(current_file_abs_path, test_paths) - local project_root = root_tests.project_root_from_test_folder(test_folder) - local project_root_length = string.len(project_root .. ps) - local from_root = string.sub(current_file_abs_path, project_root_length + 1, -1) - local src_folder_name = list.match_one(from_root, project_generic.src_folder_prefixes, '^', ps, 'no_envelope') - local src_folder_length = string.len(src_folder_name .. ps) - local from_root_without_src_folder = string.sub(from_root, src_folder_length + 1, -1) - local from_root_without_src_folder_no_ext = vim.fn.fnamemodify(from_root_without_src_folder, ':r') - return {root_tests.find_test_file(from_root_without_src_folder_no_ext, test_folder), test_folder} + local peer_test_code_file = peer.find_test_file(current_file_abs_path) + if peer_test_code_file ~= '' then + return {peer_test_code_file, folder} + else + local test_paths = root_tests.potential_test_folders(git_root) + local test_folder = root_tests.nearest_test_folder(current_file_abs_path, test_paths) + local project_root = root_tests.project_root_from_test_folder(test_folder) + local project_root_length = string.len(project_root .. ps) + local from_root = string.sub(current_file_abs_path, project_root_length + 1, -1) + local src_folder_name = list.match_one(from_root, project_generic.src_folder_prefixes, '^', ps, 'no_envelope') + local src_folder_length = string.len(src_folder_name .. ps) + local from_root_without_src_folder = string.sub(from_root, src_folder_length + 1, -1) + local from_root_without_src_folder_no_ext = vim.fn.fnamemodify(from_root_without_src_folder, ':r') + return {root_tests.find_test_file(from_root_without_src_folder_no_ext, test_folder), test_folder} + end end end end end -vim.cmd('command! FindTestOrSourceFile :lua print(GoToTestFile.find_test_or_source_file(go_to_test_file.git.repo_root_of_file(vim.fn.expand("%:p")), vim.fn.expand("%:p")))') +vim.cmd('command! FindTestOrSourceFile :lua print(GoToTestFile.find_test_or_source_file(GoToTestFile.git.repo_root_of_file(vim.fn.expand("%:p")), vim.fn.expand("%:p"))[1])') -- rename to last resort, the above should provide some sane locations even if it cannot find the file go_to_test_file.find_test_or_src_code_file_folder_on_failure = function(current_file_abs_path) @@ -60,7 +75,7 @@ go_to_test_file.find_test_or_src_code_file_folder_on_failure = function(current_ local filepath, test_path = list.unpack(go_to_test_file.find_test_or_source_file(git_root, current_file_abs_path)) local ps = path.separator(system.name) - if filepath == '.' .. ps then + if filepath == '.' .. ps or filepath == '' then if test_path ~= '' then return test_path else diff --git a/lua/go_to_test_file/path.lua b/lua/go_to_test_file/path.lua index ee1bc12..bb964db 100644 --- a/lua/go_to_test_file/path.lua +++ b/lua/go_to_test_file/path.lua @@ -21,6 +21,9 @@ path.basename = function(filepath) end path.dirname = function(filepath) + if filepath == '' then + return '' + end return vim.fn.fnamemodify(filepath, ":h") end diff --git a/lua/go_to_test_file/peer_dunder_tests.lua b/lua/go_to_test_file/peer_dunder_tests.lua new file mode 100644 index 0000000..5a1064c --- /dev/null +++ b/lua/go_to_test_file/peer_dunder_tests.lua @@ -0,0 +1,40 @@ +local path = require('go_to_test_file.path') +local system = require('go_to_test_file.system') +local cmd = require('go_to_test_file.cmd') +local list = require('go_to_test_file.list') + +local peer_dunder_tests = { + test_folder_names = {'__tests__'} +} + +peer_dunder_tests.find_source_file = function(source_folder, filename) + local ps = path.separator(system.name()) + local cmmd = cmd.cd_string(source_folder) .. " && fd --type f --max-depth=1 '" .. filename .. "' | head -1" + local output = vim.fn.trim(vim.fn.system(cmmd)):gsub('^.' .. ps, '') + if vim.v.shell_error ~= 0 then + error(output .. ' cmmd:' .. cmmd) + end + if output == '' then + return '' + else + return path.join(ps, source_folder, output) + end +end + +peer_dunder_tests.find_test_file = peer_dunder_tests.find_source_file + +peer_dunder_tests.folder_tests_folder = function(source_folder) + local ps = path.separator(system.name()) + local identifiers = string.format("^%s/?$", list.unpack(peer_dunder_tests.test_folder_names)) + local cmmd = cmd.cd_string(source_folder) .. " && fd --type d --max-depth=1 '" .. identifiers .. "' | head -1" + local output = vim.fn.trim(vim.fn.system(cmmd)):gsub('^.' .. ps, '') + if vim.v.shell_error ~= 0 then + error(output .. ' cmmd:' .. cmmd) + end + if output == '' then + return '' + else + return path.join(ps, source_folder, output) + end +end +return peer_dunder_tests diff --git a/lua/go_to_test_file/project.lua b/lua/go_to_test_file/project.lua new file mode 100644 index 0000000..8a188ee --- /dev/null +++ b/lua/go_to_test_file/project.lua @@ -0,0 +1,22 @@ +local path = require('go_to_test_file.path') +local system = require('go_to_test_file.system') +local list = require('go_to_test_file.list') +local root_tests = require('go_to_test_file.root_tests') +local peer_dunder_tests = require('go_to_test_file.peer_dunder_tests') + +local project = {} + +project.test_folder_names = vim.list_extend(vim.list_extend({}, root_tests.test_folder_names), peer_dunder_tests.test_folder_names) + +project.test_path_from_filepath = function(current_file_with_abs_path) + local ps = path.separator(system.name) + local infix_match = list.match_one(current_file_with_abs_path, project.test_folder_names, ps, ps) + if infix_match == '' then + return '' + else + local _, stop = string.find(current_file_with_abs_path, infix_match) + return string.sub(current_file_with_abs_path, 1, stop):gsub(ps .. '$', '') + end +end + +return project diff --git a/spec/go_to_test_file/project_spec.lua b/spec/go_to_test_file/project_spec.lua new file mode 100644 index 0000000..39bf189 --- /dev/null +++ b/spec/go_to_test_file/project_spec.lua @@ -0,0 +1,20 @@ +local assert = require('luassert') + +local path = require('go_to_test_file.path') +local system = require('go_to_test_file.system') +local cmd = require('go_to_test_file.cmd') +local project = require('go_to_test_file.project') + +describe('project', function() + describe('test_path_from_filepath', function() + it('returns the abs of the test folder from the path', function() + local file_folder_abs_path = path.script_path(system.name) + local cmmd = cmd.cd_string(file_folder_abs_path) .. ' && git rev-parse --show-toplevel' + local git_root = vim.fn.trim(vim.fn.system(cmmd)) + local expected = path.join(path.separator(system.name), git_root, 'spec') + local tst = path.join(path.separator(system.name), file_folder_abs_path, 'project_spec.lua') + local actual = project.test_path_from_filepath(tst) + assert.are.equal(expected, actual) + end) + end) +end)