scansion/parser.lua

Thu, 23 Mar 2023 12:14:53 +0000

author
Matthew Wild <mwild1@gmail.com>
date
Thu, 23 Mar 2023 12:14:53 +0000
changeset 172
2c17151ed21b
parent 163
0e2150680a25
permissions
-rw-r--r--

client: Fix timeout handling

Previously, the timeout handler would fire an error that would get caught and
logged by the timer code. However that error never reached the upper levels of
scansion, leading to the whole thing just hanging.

Now we just trigger resumption of the async runner, and throw the error from
there if we haven't received the stanza yet.

With this change, timeouts are now correctly handled and reported as failures.

0
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 local function parse(data)
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2 local parsed = {
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 objects = {};
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4 actions = {};
147
db39e8e9146c scansion.parser: Ensure script objects always have tags, even if empty
Matthew Wild <mwild1@gmail.com>
parents: 79
diff changeset
5 tags = {};
0
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6 };
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8 local line_number = 0;
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9 local last_object;
43
b37504fa3031 Add annotations to actions (by grabbing the preceding comment)
Matthew Wild <mwild1@gmail.com>
parents: 42
diff changeset
10 local annotation;
72
4fde8d4a4c76 scansion.parser: Whitespace fix
Matthew Wild <mwild1@gmail.com>
parents: 70
diff changeset
11
162
f888f236321f Make current line number available in all error events
Waqas Hussain <waqas20@gmail.com>
parents: 160
diff changeset
12 local function parse_error(text)
163
0e2150680a25 parser: Prefix parse errors with "ParserError: "
Waqas Hussain <waqas20@gmail.com>
parents: 162
diff changeset
13 return nil, "ParseError: " .. text .. " (line " .. line_number .. ")";
162
f888f236321f Make current line number available in all error events
Waqas Hussain <waqas20@gmail.com>
parents: 160
diff changeset
14 end
f888f236321f Make current line number available in all error events
Waqas Hussain <waqas20@gmail.com>
parents: 160
diff changeset
15
42
67d50889b7fe scansion.parser: Don't skip blank lines (otherwise line numbers get skewed)
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
16 for line in data:gmatch("([^\r\n]*)\r?\n") do
0
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17 line_number = line_number + 1;
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 if line:sub(1,1) == "[" then
79
63d573be3f91 scansion.parser: Remove unused variable (thanks luacheck)
Matthew Wild <mwild1@gmail.com>
parents: 78
diff changeset
19 local obj_type, name = line:match("^%[(%a+)%] (.+)$");
0
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21 if parsed.objects[name] then
162
f888f236321f Make current line number available in all error events
Waqas Hussain <waqas20@gmail.com>
parents: 160
diff changeset
22 return parse_error("Duplicate definition of '"..name.."'");
0
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23 end
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 parsed.objects[name] = {
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 type = obj_type:lower();
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26 name = name;
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27 defined_line = line_number;
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28 };
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29 last_object = parsed.objects[name];
47
1cbc0d9d132d scansion.parser: Allow property names to contain underscore
Kim Alvefur <zash@zash.se>
parents: 44
diff changeset
30 elseif line:match("^%s+[%a_]+:.+$") then
0
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31 if not last_object then
162
f888f236321f Make current line number available in all error events
Waqas Hussain <waqas20@gmail.com>
parents: 160
diff changeset
32 return parse_error("Unexpected outside of an object definition");
0
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33 end
47
1cbc0d9d132d scansion.parser: Allow property names to contain underscore
Kim Alvefur <zash@zash.se>
parents: 44
diff changeset
34 local k, v = line:match("^%s+([%a_]+):%s*(.+)$")
0
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35 last_object[k] = v;
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 elseif #parsed.actions > 0 and line:sub(1,1) == "\t" then
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37 table.insert(parsed.actions[#parsed.actions].extra, line:sub(2));
160
28aa762f11c7 Include line_start and line_end in action objects and action log events for /run end-point
Waqas Hussain <waqas20@gmail.com>
parents: 147
diff changeset
38 parsed.actions[#parsed.actions].line_end = line_number;
0
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 elseif line:match("^%s*$") or line:match("^#") or line:match("^([/-])%1") then
70
2b62a714b5df scansion.parser: Read any comments at top of the file as script title (first line) and summary (following lines)
Matthew Wild <mwild1@gmail.com>
parents: 47
diff changeset
40 -- Blank line or comment
2b62a714b5df scansion.parser: Read any comments at top of the file as script title (first line) and summary (following lines)
Matthew Wild <mwild1@gmail.com>
parents: 47
diff changeset
41 local in_header = (next(parsed.objects) == nil) and (next(parsed.actions) == nil);
2b62a714b5df scansion.parser: Read any comments at top of the file as script title (first line) and summary (following lines)
Matthew Wild <mwild1@gmail.com>
parents: 47
diff changeset
42 if in_header and #line > 0 then
77
38066f635004 Ignore shebangs at the top of a script
Matthew Wild <mwild1@gmail.com>
parents: 72
diff changeset
43 if not parsed.title and not line:match("^#!") then
70
2b62a714b5df scansion.parser: Read any comments at top of the file as script title (first line) and summary (following lines)
Matthew Wild <mwild1@gmail.com>
parents: 47
diff changeset
44 parsed.title = line:gsub("^[#-]+%s*", "");
78
54bb54fe9ed2 main, scansion.parser: Allow scripts to include tags in comments at the beginning, which are included in JSON output
Matthew Wild <mwild1@gmail.com>
parents: 77
diff changeset
45 elseif line:match("^##") then
54bb54fe9ed2 main, scansion.parser: Allow scripts to include tags in comments at the beginning, which are included in JSON output
Matthew Wild <mwild1@gmail.com>
parents: 77
diff changeset
46 local tag = line:gsub("^##%s*", "");
54bb54fe9ed2 main, scansion.parser: Allow scripts to include tags in comments at the beginning, which are included in JSON output
Matthew Wild <mwild1@gmail.com>
parents: 77
diff changeset
47 local k, v = tag:match("^([^:]+):%s*(.+)$");
54bb54fe9ed2 main, scansion.parser: Allow scripts to include tags in comments at the beginning, which are included in JSON output
Matthew Wild <mwild1@gmail.com>
parents: 77
diff changeset
48 if k then
54bb54fe9ed2 main, scansion.parser: Allow scripts to include tags in comments at the beginning, which are included in JSON output
Matthew Wild <mwild1@gmail.com>
parents: 77
diff changeset
49 -- Tag format: ## tagkey:tagvalue
54bb54fe9ed2 main, scansion.parser: Allow scripts to include tags in comments at the beginning, which are included in JSON output
Matthew Wild <mwild1@gmail.com>
parents: 77
diff changeset
50 parsed.tags[k] = v;
54bb54fe9ed2 main, scansion.parser: Allow scripts to include tags in comments at the beginning, which are included in JSON output
Matthew Wild <mwild1@gmail.com>
parents: 77
diff changeset
51 else
54bb54fe9ed2 main, scansion.parser: Allow scripts to include tags in comments at the beginning, which are included in JSON output
Matthew Wild <mwild1@gmail.com>
parents: 77
diff changeset
52 -- Tag format: ## tagfoobar
54bb54fe9ed2 main, scansion.parser: Allow scripts to include tags in comments at the beginning, which are included in JSON output
Matthew Wild <mwild1@gmail.com>
parents: 77
diff changeset
53 parsed.tags[tag] = true;
54bb54fe9ed2 main, scansion.parser: Allow scripts to include tags in comments at the beginning, which are included in JSON output
Matthew Wild <mwild1@gmail.com>
parents: 77
diff changeset
54 end
70
2b62a714b5df scansion.parser: Read any comments at top of the file as script title (first line) and summary (following lines)
Matthew Wild <mwild1@gmail.com>
parents: 47
diff changeset
55 else
2b62a714b5df scansion.parser: Read any comments at top of the file as script title (first line) and summary (following lines)
Matthew Wild <mwild1@gmail.com>
parents: 47
diff changeset
56 parsed.summary = (parsed.summary and parsed.summary.."\n" or "")..line:gsub("^[#-]+%s*", "");
43
b37504fa3031 Add annotations to actions (by grabbing the preceding comment)
Matthew Wild <mwild1@gmail.com>
parents: 42
diff changeset
57 end
b37504fa3031 Add annotations to actions (by grabbing the preceding comment)
Matthew Wild <mwild1@gmail.com>
parents: 42
diff changeset
58 else
70
2b62a714b5df scansion.parser: Read any comments at top of the file as script title (first line) and summary (following lines)
Matthew Wild <mwild1@gmail.com>
parents: 47
diff changeset
59 -- Save as annotation for the following action
2b62a714b5df scansion.parser: Read any comments at top of the file as script title (first line) and summary (following lines)
Matthew Wild <mwild1@gmail.com>
parents: 47
diff changeset
60 if #line == 0 then
2b62a714b5df scansion.parser: Read any comments at top of the file as script title (first line) and summary (following lines)
Matthew Wild <mwild1@gmail.com>
parents: 47
diff changeset
61 if annotation then
2b62a714b5df scansion.parser: Read any comments at top of the file as script title (first line) and summary (following lines)
Matthew Wild <mwild1@gmail.com>
parents: 47
diff changeset
62 annotation.closed = true;
2b62a714b5df scansion.parser: Read any comments at top of the file as script title (first line) and summary (following lines)
Matthew Wild <mwild1@gmail.com>
parents: 47
diff changeset
63 end
2b62a714b5df scansion.parser: Read any comments at top of the file as script title (first line) and summary (following lines)
Matthew Wild <mwild1@gmail.com>
parents: 47
diff changeset
64 elseif annotation or not line:match("^%-+$") then
2b62a714b5df scansion.parser: Read any comments at top of the file as script title (first line) and summary (following lines)
Matthew Wild <mwild1@gmail.com>
parents: 47
diff changeset
65 if (not annotation) or annotation.closed then
2b62a714b5df scansion.parser: Read any comments at top of the file as script title (first line) and summary (following lines)
Matthew Wild <mwild1@gmail.com>
parents: 47
diff changeset
66 annotation = { line };
2b62a714b5df scansion.parser: Read any comments at top of the file as script title (first line) and summary (following lines)
Matthew Wild <mwild1@gmail.com>
parents: 47
diff changeset
67 else
2b62a714b5df scansion.parser: Read any comments at top of the file as script title (first line) and summary (following lines)
Matthew Wild <mwild1@gmail.com>
parents: 47
diff changeset
68 table.insert(annotation, line);
2b62a714b5df scansion.parser: Read any comments at top of the file as script title (first line) and summary (following lines)
Matthew Wild <mwild1@gmail.com>
parents: 47
diff changeset
69 end
43
b37504fa3031 Add annotations to actions (by grabbing the preceding comment)
Matthew Wild <mwild1@gmail.com>
parents: 42
diff changeset
70 end
b37504fa3031 Add annotations to actions (by grabbing the preceding comment)
Matthew Wild <mwild1@gmail.com>
parents: 42
diff changeset
71 end
0
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 else
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 last_object = nil;
44
0dab1dc183c1 parser, objects.client: Experimental support for more liberal object names
Matthew Wild <mwild1@gmail.com>
parents: 43
diff changeset
74 local name, action, extra = line:match("^([^:]+) (%a+):?%s?(.*)$");
0
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75 if not name then
162
f888f236321f Make current line number available in all error events
Waqas Hussain <waqas20@gmail.com>
parents: 160
diff changeset
76 return parse_error("Unable to parse action");
0
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77 end
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78 if not parsed.objects[name] then
162
f888f236321f Make current line number available in all error events
Waqas Hussain <waqas20@gmail.com>
parents: 160
diff changeset
79 return parse_error("The object '"..name.."' was not declared");
0
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 end
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81 table.insert(parsed.actions, {
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 object_name = name;
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
83 action = action:lower();
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
84 extra = {#extra>0 and extra or nil};
43
b37504fa3031 Add annotations to actions (by grabbing the preceding comment)
Matthew Wild <mwild1@gmail.com>
parents: 42
diff changeset
85 annotation = annotation and table.concat(annotation, "\n") or nil;
160
28aa762f11c7 Include line_start and line_end in action objects and action log events for /run end-point
Waqas Hussain <waqas20@gmail.com>
parents: 147
diff changeset
86 line_start = line_number;
28aa762f11c7 Include line_start and line_end in action objects and action log events for /run end-point
Waqas Hussain <waqas20@gmail.com>
parents: 147
diff changeset
87 line_end = line_number;
0
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
88 });
43
b37504fa3031 Add annotations to actions (by grabbing the preceding comment)
Matthew Wild <mwild1@gmail.com>
parents: 42
diff changeset
89 annotation = nil;
0
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
90 end
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
91 end
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92 return parsed;
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93 end
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95 return {
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96 parse = parse;
2e31b584f8d9 It is better to write and run incomplete tests than not to run complete tests. -- Martin Fowler
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 };

mercurial