Skip to content

Commit

Permalink
fix: presenting incorrect results when using Swift Testing (#250)
Browse files Browse the repository at this point in the history
Resolves #249
  • Loading branch information
wojciech-kulik authored Nov 19, 2024
1 parent dfdab9b commit 77ef9b1
Show file tree
Hide file tree
Showing 9 changed files with 268 additions and 22 deletions.
2 changes: 1 addition & 1 deletion lua/xcodebuild/core/xcode.lua
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ function M.get_destinations(projectFile, scheme, workingDirectory, callback)
on_stdout = function(_, output)
local result = {}
local foundDestinations = false
local valuePattern = "%:%s*([^@}]-)%s*[@}]"
local valuePattern = ":%s*([^@}]-)%s*[@}]"

for _, line in ipairs(output) do
local trimmedLine = util.trim(line)
Expand Down
2 changes: 1 addition & 1 deletion lua/xcodebuild/tests/diagnostics.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ local function find_test_class(bufnr, report)
-- if not try finding the name in the source code
local lines = vim.api.nvim_buf_get_lines(bufnr, 1, -1, false)
for index, line in ipairs(lines) do
local class = string.match(line, "class ([^:%s]+)%s*%:?")
local class = string.match(line, "class ([^:%s]+)%s*:?")
local previousLine = (index > 1 and lines[index - 1]) or ""
if not string.find(line, "@Suite") and not string.find(previousLine, "@Suite") and class then
return testSearch.get_test_key_for_file(filepath, class)
Expand Down
2 changes: 1 addition & 1 deletion lua/xcodebuild/tests/provider.lua
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function M.find_tests(opts)
local selectedTests = {}

for _, line in ipairs(lines) do
selectedClass = string.match(line, "class ([^:%s]+)%s*%:?")
selectedClass = string.match(line, "class ([^:%s]+)%s*:?")
if selectedClass then
break
end
Expand Down
14 changes: 12 additions & 2 deletions lua/xcodebuild/tests/xcresult_parser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ local function extract_error(message)
return nil
end

local filename, lineNumber, error = message:match("(.+)%:(%d+)%: (.*)")
local filename, lineNumber, error = message:match("(.+):(%d+): (.*)")
if not error then
return { message = message }
end
Expand Down Expand Up @@ -208,7 +208,7 @@ local function parse_test(testNode, targetId)
swiftTestingId = testId,
target = targetIdUnwrapped,
class = suiteName:gsub("/", " "),
name = testNode.name and testNode.name:gsub("%(%)", ""):gsub("/", " "),
name = testNode.name and testNode.name:gsub("%([^%)]*%)", ""):gsub("/", " "),
testResult = testNode.result == "Passed" and "passed" or "failed",
success = testNode.result == "Passed",
time = testNode.duration and testNode.duration:gsub("s", " seconds"):gsub(",", "."),
Expand Down Expand Up @@ -311,7 +311,17 @@ function M.fill_xcresult_data(report)
end

ripgrepCache = {}

report.tests = get_tests(outputDecoded.testNodes[1])
report.failedTestsCount = 0
report.testsCount = 0

for _, tests in pairs(report.tests) do
for _, test in ipairs(tests) do
report.failedTestsCount = report.failedTestsCount + (test.success and 0 or 1)
report.testsCount = report.testsCount + 1
end
end

return true
end
Expand Down
2 changes: 1 addition & 1 deletion lua/xcodebuild/xcode_logs/panel.lua
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ local function open_test_file(tests)
return
end

local testTarget, testClass, testName, line = string.match(currentLine, "([%w_]*)%.?([%w_]*)%.(.*)%:(%d+)")
local testTarget, testClass, testName, line = string.match(currentLine, "([%w_]*)%.?([%w_]*)%.(.*):(%d+)")
local key = testSearch.get_test_key(testTarget, testClass)

for _, test in ipairs(tests[key] or {}) do
Expand Down
43 changes: 27 additions & 16 deletions lua/xcodebuild/xcode_logs/parser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ local usesSwiftTesting = false
local xcresultFilepath = nil

-- patterns
local swiftFilePattern = "[^%:]+%.swift"
local xcTestLogPattern = "%s+[%w_]+%[%d+%:%d+%]"
local swiftFilePattern = "[^:]+%.swift"
local xcTestLogPattern = "%s+[%w_]+%[%d+:%d+%]"

local DEBUG = false

Expand Down Expand Up @@ -295,7 +295,7 @@ end
---@param logLine string
---@return string
local function get_message(logLine)
return string.match(logLine, "%-%[[%w_]+%.[%w_]+ %g+%] %: (.*)") or logLine
return string.match(logLine, "%-%[[%w_]+%.[%w_]+ %g+%] : (.*)") or logLine
end

---Returns the first match line number or nil.
Expand Down Expand Up @@ -327,9 +327,9 @@ local function parse_build_error(line)
return
end

if string.find(line, swiftFilePattern .. "%:%d+%:%d*%:? %w*%s*error%: .*") then
if string.find(line, swiftFilePattern .. ":%d+:%d*:? %w*%s*error: .*") then
local filepath, lineNumber, colNumber, message =
string.match(line, "(" .. swiftFilePattern .. ")%:(%d+)%:(%d*)%:? %w*%s*error%: (.*)")
string.match(line, "(" .. swiftFilePattern .. "):(%d+):(%d*):? %w*%s*error: (.*)")
if filepath and message then
lineType = BUILD_ERROR
lineData = {
Expand All @@ -341,8 +341,8 @@ local function parse_build_error(line)
}
end
else
local source, message = string.match(line, "(.*)%: %w*%s*error%: (.*)")
message = message or string.match(line, "^error%: (.*)")
local source, message = string.match(line, "(.*): %w*%s*error: (.*)")
message = message or string.match(line, "^error: (.*)")

if message then
lineType = BUILD_ERROR
Expand All @@ -365,17 +365,24 @@ local function parse_test_error(line)
end

local filepath, lineNumber, message =
string.match(line, "(" .. swiftFilePattern .. ")%:(%d+)%:%d*%:? %w*%s*error%: (.*)")
string.match(line, "(" .. swiftFilePattern .. "):(%d+):%d*:? %w*%s*error: (.*)")
local filename = filepath and util.get_filename(filepath)
lineData.filepath = lineData.filepath or filepath

if string.find(line, "recorded an issue") then
if string.find(line, "recorded an issue at") then
filename, lineNumber, message =
string.match(line, "recorded an issue at (" .. swiftFilePattern .. "):(%d+):%d+: (.*)")
filepath = testSearch.find_filepath_by_filename(filename)

lineData.filename = lineData.filename or filename
lineData.filepath = lineData.filepath or filepath
lineData.filename = filename
lineData.filepath = filepath
elseif string.find(line, "recorded an issue") then
filename, lineNumber, message =
string.match(line, " at (" .. swiftFilePattern .. "):(%d+):%d+: Caught error: (.*)")
filepath = testSearch.find_filepath_by_filename(filename)

lineData.filename = filename
lineData.filepath = filepath
end

if not filepath or not message then
Expand Down Expand Up @@ -419,7 +426,7 @@ local function parse_warning(line)
end

local filepath, lineNumber, columnNumber, message =
string.match(line, "(" .. swiftFilePattern .. ")%:(%d+)%:(%d*)%:? %w*%s*warning%: (.*)")
string.match(line, "(" .. swiftFilePattern .. "):(%d+):(%d*):? %w*%s*warning: (.*)")

if filepath and message and util.has_prefix(filepath, vim.fn.getcwd()) then
lineType = BUILD_WARNING
Expand Down Expand Up @@ -520,7 +527,8 @@ local function parse_test_started(line)
if not testName then
target = constants.SwiftTestingTarget
testClass = testSuite or constants.SwiftTestingGlobal
testName = string.match(line, '^[^%w]+ Test "([^"]+)"') or string.match(line, "^[^%w]+ Test (%g+)%(%)")
testName = string.match(line, '^[^%w]+ Test "([^"]+)"')
or string.match(line, "^[^%w]+ Test (%g+)%([^%)]*%)")
testName = testName and testName:gsub("/", " ")
end

Expand Down Expand Up @@ -572,6 +580,9 @@ local function process_line(line)
end

parse_test_started(line)
elseif string.find(line, "◇ Passing") then
-- do nothing
return
elseif
string.find(line, "^Test [Cc]ase.*passed")
or string.find(line, "^Test [Cc]ase.*failed")
Expand All @@ -583,7 +594,7 @@ local function process_line(line)
flush() -- flush if there is anything
line = line:gsub("on '[^']*'", "") -- remove simulator name (it appears while parallel testing)
parse_test_finished(line)
elseif string.find(line, "error%:") or string.find(line, "recorded an issue") then
elseif string.find(line, "error:") or string.find(line, "recorded an issue") then
flush()

-- found another failure within the same test
Expand All @@ -597,7 +608,7 @@ local function process_line(line)
elseif testsCount == 0 and lineType == BEGIN then
parse_build_error(line)
end
elseif string.find(line, "warning%:") then
elseif string.find(line, "warning:") then
flush()
parse_warning(line)
elseif string.find(line, "%s*~*%^~*%s*") then
Expand All @@ -608,7 +619,7 @@ local function process_line(line)
if lineType ~= TEST_ERROR then
flush()
end
elseif string.find(line, "^Linting") or string.find(line, "^note%:") then
elseif string.find(line, "^Linting") or string.find(line, "^note:") then
flush()
elseif string.find(line, "%.xcresult$") then
xcresultFilepath = string.match(line, "%s*(.*[^%.%/]+%.xcresult)")
Expand Down
21 changes: 21 additions & 0 deletions specs/parser_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ local mockSwiftFiles = function()
},
}
end

---@diagnostic disable-next-line: duplicate-set-field
require("xcodebuild.tests.search").find_filepath_by_filename = function(filename)
if filename == "CliClientTests.swift" then
return "/Users/john/repo/something/Tests/CliClientTests.swift"
elseif filename == "HeckelAlgorithmSwiftTestingTests.swift" then
return "/Users/john/repo/something/Tests/HeckelAlgorithmSwiftTestingTests.swift"
elseif filename == "TestingProjectTests.swift" then
return "/Users/john/repo/something/Tests/TestingProjectTests.swift"
end
end
end

local mockLSP = function()
Expand Down Expand Up @@ -306,4 +317,14 @@ describe("ENSURE parse_logs", function()
assert.are.same(expectedResult, result)
end)
end)

--
-- SwiftTesting parameterized
--
describe("WHEN the project contains SwiftTesting tests with parameters", function()
it("THEN should parse test results", function()
local expectedResult, result = runTestCase(23)
assert.are.same(expectedResult, result)
end)
end)
end)
Loading

0 comments on commit 77ef9b1

Please sign in to comment.