-
-
Notifications
You must be signed in to change notification settings - Fork 83
Expand file tree
/
Copy pathresult-parser.lua
More file actions
215 lines (173 loc) · 4.93 KB
/
result-parser.lua
File metadata and controls
215 lines (173 loc) · 4.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
local class = require('java-core.utils.class')
local MessageId = require('java-test.results.message-id')
local TestStatus = require('java-test.results.result-status')
local TestExecStatus = require('java-test.results.execution-status')
---@class java-test.TestParser
---@field private test_details java-test.TestResults[]
local TestParser = class()
---Init
function TestParser:_init()
self.test_details = {}
end
---@private
TestParser.node_parsers = {
[MessageId.TestTree] = 'parse_test_tree',
[MessageId.TestStart] = 'parse_test_start',
[MessageId.TestEnd] = 'parse_test_end',
[MessageId.TestFailed] = 'parse_test_failed',
[MessageId.TestError] = 'parse_test_failed',
}
---@private
TestParser.skip_prefixes = {
'@Ignore:',
'@AssumptionFailure:',
}
---@private
TestParser.strtobool = {
['true'] = true,
['false'] = false,
}
---Parse a given text into test details
---@param text string test result buffer
function TestParser:parse(text)
if text:sub(-1) ~= '\n' then
text = text .. '\n'
end
local line_iter = text:gmatch('(.-)\n')
local line = line_iter()
while line ~= nil do
local message_id = line:sub(1, 8):gsub('%s+', '')
local content = line:sub(9)
local node_parser = TestParser.node_parsers[message_id]
if node_parser then
local data = vim.split(content, ',', { plain = true, trimempty = true })
if self[TestParser.node_parsers[message_id]] then
self[TestParser.node_parsers[message_id]](self, data, line_iter)
end
end
line = line_iter()
end
end
---Returns the parsed test details
---@return java-test.TestResults # parsed test details
function TestParser:get_test_details()
return self.test_details
end
---@private
function TestParser:parse_test_tree(data)
local node = {
test_id = tonumber(data[1]),
test_name = data[2],
is_suite = TestParser.strtobool[data[3]],
test_count = tonumber(data[4]),
is_dynamic_test = TestParser.strtobool[data[5]],
parent_id = tonumber(data[6]),
display_name = data[7],
parameter_types = data[8],
unique_id = data[9],
}
local parent = self:find_result_node(node.parent_id)
if not parent then
table.insert(self.test_details, node)
else
parent.children = parent.children or {}
table.insert(parent.children, node)
end
end
---@private
function TestParser:parse_test_start(data)
local test_id = tonumber(data[1])
local node = self:find_result_node(test_id)
assert(node)
node.result = {}
node.result.execution = TestExecStatus.Started
end
---@private
function TestParser:parse_test_end(data)
local test_id = tonumber(data[1])
local node = self:find_result_node(test_id)
assert(node)
node.result.execution = TestExecStatus.Ended
for _, prefix in ipairs(TestParser.skip_prefixes) do
if string.match(data[2], '^' .. prefix) then
node.result.status = TestStatus.Skipped
end
end
end
---@private
function TestParser:parse_test_failed(data, line_iter)
local test_id = tonumber(data[1])
local node = self:find_result_node(test_id)
assert(node)
node.result.status = node.result.status or TestStatus.Failed
for _, prefix in ipairs(TestParser.skip_prefixes) do
if string.match(data[2], '^' .. prefix) then
node.result.status = TestStatus.Skipped
end
end
while true do
local line = line_iter()
if line == nil then
break
end
-- EXPECTED
if vim.startswith(line, MessageId.ExpectStart) then
node.result.expected = self:get_content_until_end_tag(MessageId.ExpectEnd, line_iter)
-- ACTUAL
elseif vim.startswith(line, MessageId.ActualStart) then
node.result.actual = self:get_content_until_end_tag(MessageId.ActualEnd, line_iter)
-- TRACE
elseif vim.startswith(line, MessageId.TraceStart) then
node.result.trace = self:get_content_until_end_tag(MessageId.TraceEnd, line_iter)
end
end
end
---@private
function TestParser:get_content_until_end_tag(end_tag, line_iter)
local content = {}
while true do
local line = line_iter()
if line == nil or vim.startswith(line, end_tag) then
break
end
table.insert(content, line)
end
return content
end
---@private
function TestParser:find_result_node(id)
local function find_node(nodes)
if not nodes or #nodes == 0 then
return
end
for _, node in ipairs(nodes) do
if node.test_id == id then
return node
end
local _node = find_node(node.children)
if _node then
return _node
end
end
end
return find_node(self.test_details)
end
return TestParser
---@class java-test.TestResultExecutionDetails
---@field actual string[] lines
---@field expected string[] lines
---@field status java-test.TestStatus
---@field execution java-test.TestExecutionStatus
---@field trace string[] lines
---@class java-test.TestResults
---@field display_name string
---@field is_dynamic_test boolean
---@field is_suite boolean
---@field parameter_types string
---@field parent_id integer
---@field test_count integer
---@field test_id integer
---@field test_name string
---@field unique_id string
---@field result java-test.TestResultExecutionDetails
---@field children java-test.TestResults[]