Skip to content

Commit

Permalink
feat: allow support for monorepos
Browse files Browse the repository at this point in the history
  • Loading branch information
MisanthropicBit authored Oct 2, 2023
1 parent 765a4e9 commit 68f0e97
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 22 deletions.
19 changes: 13 additions & 6 deletions lua/neotest-mocha/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ local Adapter = { name = "neotest-mocha" }
---@return string | nil @Absolute root dir of test suite
Adapter.root = lib.files.match_root_pattern "package.json"

---@async
---@param file_path string
---@return boolean
local default_is_test_file = util.create_test_file_extensions_matcher(
{ "spec", "test" },
{ "js", "mjs", "cjs", "jsx", "coffee", "ts", "tsx" }
Expand All @@ -42,7 +39,17 @@ local is_test_file = default_is_test_file
---@param file_path string
---@return boolean
function Adapter.is_test_file(file_path)
return is_test_file(file_path)
local rootPath = util.find_package_json_ancestor(file_path)

if not rootPath then
return false
end

-- This is a test file if it matches the supported extensions and a parent directory
-- contains a package.json file with mocha installed. The latter is necessary to
-- support monorepos where there are multiple parent directories with a package.json
-- and the current file's position in the monorepo has to be taken into account as well
return is_test_file(file_path) and util.has_package_dependency(rootPath, "mocha")
end

---Filter directories when searching for test files
Expand All @@ -56,13 +63,13 @@ function Adapter.filter_dir(name)
end

---@param s string
---@param boolean
---@return boolean
local function isTemplateLiteral(s)
return string.sub(s, 1, 1) == "`"
end

---@param s string
---@param string
---@return string
local function getStringFromTemplateLiteral(s)
local matched = string.match(s, "^`(.*)`$")
if not matched then
Expand Down
54 changes: 51 additions & 3 deletions lua/neotest-mocha/util.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local vim = vim
local validate = vim.validate
local uv = vim.loop
local lib = require "neotest.lib"

local M = {}

Expand Down Expand Up @@ -339,9 +340,9 @@ function M.parsed_json_to_results(data, tree, consoleOut)
return tests
end

---@param intermediate_extensions Array
---@param end_extensions Array
---@return function
---@param intermediate_extensions string[]
---@param end_extensions string[]
---@return fun(file_path: string): boolean
function M.create_test_file_extensions_matcher(intermediate_extensions, end_extensions)
return function(file_path)
if file_path == nil then
Expand All @@ -360,4 +361,51 @@ function M.create_test_file_extensions_matcher(intermediate_extensions, end_exte
end
end

---@param dependencies table<string, string>?
---@param packageName string
---@return boolean
local function _has_package_dependency(dependencies, packageName)
for key, _ in pairs(dependencies or {}) do
if key == packageName then
return true
end
end

return false
end

---@param path string
---@param packageName string
---@return boolean
function M.has_package_dependency(path, packageName)
local fullPath = path .. "/package.json"

if not lib.files.exists(fullPath) then
return false
end

local ok, packageJsonContent = pcall(lib.files.read, fullPath)

if not ok then
print "cannot read package.json"
return false
end

local parsedPackageJson = vim.json.decode(packageJsonContent)

if not parsedPackageJson then
return false
end

if _has_package_dependency(parsedPackageJson["dependencies"], packageName) then
return true
end

if _has_package_dependency(parsedPackageJson["devDependencies"], packageName) then
return true
end

return false
end

return M
33 changes: 20 additions & 13 deletions test/basic_spec.lua
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
local async = require "plenary.async.tests"
local async = require("nio").tests
local neotest_async = require "neotest.async"
local basic_test_positions = require "test.fixtures.basic_test_positions"
local MockTree = require "test.helpers.mock_tree"
local plugin = require "neotest-mocha" {
mochaCommand = "mocha",
}
local util = require "neotest-mocha.util"
local stub = require "luassert.stub"

describe("is_test_file", function()
local supported_extensions = { "js", "mjs", "cjs", "jsx", "coffee", "ts", "tsx" }
local find_package_json_ancestor_stub
local has_package_dependency_stub

it("matches mocha test files", function()
-- by folder name.
for _, extension in ipairs(supported_extensions) do
assert.True(plugin.is_test_file("./test/basic." .. extension))
end
before_each(function()
find_package_json_ancestor_stub = stub(util, "find_package_json_ancestor").returns "./root/"
has_package_dependency_stub = stub(util, "has_package_dependency").returns(true)
end)

after_each(function()
find_package_json_ancestor_stub:revert()
has_package_dependency_stub:revert()
end)

-- by file name.
it("matches mocha test files", function()
for _, extension in ipairs(supported_extensions) do
assert.True(plugin.is_test_file("./src/basic.test." .. extension))
end
Expand All @@ -26,16 +33,16 @@ describe("is_test_file", function()
assert.False(plugin.is_test_file "./src/index.js")
end)

it("does not mark a file as a test if mocha is not installed", function()
has_package_dependency_stub.returns(false)

assert.False(plugin.is_test_file "./src/basic.test.js")
end)

it("matches mocha test files with configurable test patterns", function()
local intermediate_extensions = { "spec", "test", "lollipop" }
local is_test_file = util.create_test_file_extensions_matcher(intermediate_extensions, supported_extensions)

-- by folder name.
for _, extension in ipairs(supported_extensions) do
assert.True(is_test_file("./test/basic." .. extension))
end

-- by file name.
for _, extension1 in ipairs(intermediate_extensions) do
for _, extension2 in ipairs(supported_extensions) do
assert.True(is_test_file("./src/basic." .. extension1 .. "." .. extension2))
Expand Down

0 comments on commit 68f0e97

Please sign in to comment.